題目描述 Description
某國為了防御敵國的導彈襲擊,發展出一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以后每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的導彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的導彈。
輸入描述 Input Description
輸入導彈依次飛來的高度(雷達給出的高度數據是不大於30000的正整數)
輸出描述 Output Description
輸出這套系統最多能攔截多少導彈,如果要攔截所有導彈最少要配備多少套這種導彈攔截系統。
樣例輸入 Sample Input
389 207 155 300 299 170 158 65
樣例輸出 Sample Output
6
2
數據范圍及提示 Data Size & Hint
導彈的高度<=30000,導彈個數<=20
分析:
第一問是求最長不上升序列,通過狀態轉移方程:
dp[j]=1(j← 0 to 導彈個數-1)
dp[j]=max{dp[j],dp[k]+1}(high[k]>=high[j])
再看第二問,求的是最少分幾個最長不上升序列。接下來要涉及到一個優美的定理(不要問為什么優美)。
Dilworth定理:對於一個偏序集,最少鏈划分等於最長反鏈長度。
Dilworth定理的對偶定理:對於一個偏序集,其最少反鏈划分數等於其最長鏈的長度。
也就是說把一個數列划分成最少的最長不升子序列的數目就等於這個數列的最長上升子序列的長度。
因此第二問的狀態轉移方程是:
dp2[j]=1(j← 0 to 導彈個數-1)
dp2[j]=max{dp2[j],dp2[k]+1}(high[k]<=high[j])
代碼:
#include<iostream> #include<algorithm> using namespace std; const int maxdaodan=20+5; int dp[maxdaodan],dp2[maxdaodan],high[maxdaodan],ans=0,ans2=0,daodan=0; int main() { while(cin>>high[daodan]) { dp[daodan]=1; dp2[daodan]=1; daodan++; } for(int j=0; j<daodan; j++) { for(int k=0; k<j; k++) { if(high[k]>=high[j]) dp[j]=max(dp[j],dp[k]+1); if(high[k]<=high[j]) dp2[j]=max(dp2[j],dp2[k]+1); } ans=max(ans,dp[j]); ans2=max(ans2,dp2[j]); } cout<<ans<<endl<<ans2<<endl; }
想明白Dilworth定理的學霸們,請繼續閱讀:
偏序集的定義:偏序是在集合X上的二元關系≤(這只是個抽象符號,不是“小於或等於”,它滿足自反性、反對稱性和傳遞性)。即,對於X中的任意元素a,b和c,有:
(1)自反性:a≤a;
(2)反對稱性:如果a≤b且b≤a,則有a=b;
(3)傳遞性:如果a≤b且b≤c,則a≤c 。
帶有偏序關系的集合稱為偏序集。
令(X,≤)是一個偏序集,對於集合中的兩個元素a、b,如果有a≤b或者b≤a,則稱a和b是可比的,否則a和b不可比。
在這個例子(反鏈)中元素Ri<=Rj是指(i<=j) and (ai>=aj)
一個反鏈A是X的一個子集,它的任意兩個元素都不能進行比較。
一個鏈C是X的一個子集,它的任意兩個元素都可比。
【定理】
在X中,對於元素a,如果任意元素b,都有a≤b,則稱a為極小元。
定理1:令(X,≤)是一個有限偏序集,並令r是其最大鏈的大小。則X可以被划分成r個但不能再少的反鏈。
其對偶定理稱為Dilworth定理:
令(X,≤)是一個有限偏序集,並令m是反鏈的最大的大小。則X可以被划分成m個但不能再少的鏈。
雖然這兩個定理內容相似,但第一個定理證明要簡單一些。此處就只證明定理1。
證明:設p為最少反鏈個數
(1)先證明X不能划分成小於r個反鏈。由於r是最大鏈C的大小,C中任兩個元素都可比,因此C中任兩個元素都不能屬於同一反
鏈。所以p>=r。
(2)設X1=X,A1是X1中的極小元的集合。從X1中刪除A1得到X2。注意到對於X2中任意元素a2,必存在X1中的元素a1,使得
a1<=a2。令A2是X2中極小元的集合,從X2中刪除A2得到X3……,最終會有一個Xk非空而Xk+1為空。於是A1,A2,…,Ak就是X的
反鏈的划分,同時存在鏈a1<=a2<=…<=ak,其中ai在Ai內。由於r是最長鏈大小,因此r>=k。由於X被划分成了k個反鏈,因此
r>=k>=p。
(3)因此r=p,定理1得證。
【解決】
要求最少的覆蓋,按照Dilworth定理
最少鏈划分 = 最長反鏈長度
所以最少系統 = 最長導彈高度上升序列長度。