首先找最長不上公升子串行,即最多可攔截飛彈數。那麼這裡我們可以用dp來求,但顯然n2的複雜度只能拿到100分,所以我們採用貪心:每次都只用與飛彈高度最接近的系統進行攔截。至於查詢最接近的系統,這裡既可以採用列舉的方式也可以採用二分的方式~~(都能過的原因可能是資料太水)~~
再者要求最長上公升子串行,即最少系統數,至於證明……
有趣的是這裡的查詢也可以用二分,此處我用了stl中的函式
#include
using
namespace std;
int a[
140000
],n=
1,dp[
140000
],x[
140000];
bool
cmp(
int a,
int b)
intmain()
int ans=0;
int*ans1=
upper_bound
(x+1
,x+num1+
1,a[i]
,cmp)
;int
*h=&x[1]
;/*cout
=a[i];}
int num=0;
for(
int i=
1; i<=n; i++
)int ans;
int*ans1=
lower_bound
(x+1
,x+num+
1,a[i]);
int*h=
&x[1];
/*cout<=a[i]) break;
printf("%d %d\n",num,ans);*/
x[ans1-h+1]
=a[i];}
printf
("%d\n%d"
,num1,num)
;return0;
}
一點有趣的小知識:
1.eof在視窗式輸入輸出除錯的時候可通過ctrl+z結束輸入
2.二分可直接利用stl的庫函式:
lower_bound()和upper_bound()實現二分查詢,介紹一下二者的用法:
一、當陣列為公升序時:
lower_bound( begin,end,num):從陣列的begin位置到end-1位置二分查詢第乙個大於或等於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。
upper_bound( begin,end,num):從陣列的begin位置到end-1位置二分查詢第乙個大於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。
一、當陣列為降序時,需要過載函式:
lower_bound( begin,end,num,greater() ):從陣列的begin位置到end-1位置二分查詢第乙個小於或等於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。
upper_bound( begin,end,num,greater() ):從陣列的begin位置到end-1位置二分查詢第乙個小於num的數字,找到返回該數字的位址,不存在則返回end。通過返回的位址減去起始位址begin,得到找到數字在陣列中的下標。
lower_bound的過載與sort一致
3.這裡的證明涉及到了dilworth定理雖然我也不知道是啥
P1020 飛彈攔截
題目描述 某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度...
P1020 飛彈攔截
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...
P1020 飛彈攔截
原題鏈結 貪心 記錄每套系統攔截過的最小高度 新來的飛彈 如果高於所有飛彈的最低高度 那就只能再加一套了嘛 如果低於某些系統的最低高度 那就貪心 把它加到 最低高度最低的一套系統內 include include include include include include include inc...