某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。
輸入飛彈依次飛來的高度(雷達給出的高度資料是\le 50000≤50000的正整數),計算這套系統最多能攔截多少飛彈,如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
輸入格式:
1行,若干個整數(個數\le 100000≤100000)
輸出格式:
22行,每行乙個整數,第乙個數字表示這套系統最多能攔截多少飛彈,第二個數字表示如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
輸入樣例#1:複製
389 207 155 300 299 170 158 65輸出樣例#1:複製
6為了讓大家更好地測試n方演算法,本題開啟spj,n方100分,nlogn200分2
每點兩問,按問給分
下面是n*n複雜度的演算法
主要思考就是我們每次在選不選第i個的時候,都去遍歷之前的點,考慮以他們為最後乙個點的情況,所以大小就是max(res[j]+1,1),但是我們max是記錄最大值的,所以還要和自己取乙個最大值,然後把n次中最大的值取成結果。
至於需要多少個系統,可以用dilworth知道,他的系統的個數就是反鍊錶的最大的長度。,所以就是最大上公升序列的長度。
#include#include#includeusing namespace std;
int a[100002] ;
int res[100002];
int main()
res[i] = max(max,res[i]);
re = max(re, res[i]);
}cout << re<< endl;
return 0;
}
如果採用二分的做法
我們開乙個f陣列來表示長度為i的上公升子鏈的最小值,用1個ans來記錄當前最長鏈的長度,
如果a[i]<=f[ans], 則 ans++, f[ans]=a[i];
否則就二分查詢恰好以a[i]為結尾的子鏈的位置,並判斷是否更新它。
f[i]儲存長度為i時該單調序列的結束點。通過下面的舉例分析說明。記ans為當前最大標記。
做法類似這個圖。
還有乙個需要注意的就是二分的寫法。二分最好寫成左閉右開的情況。
最好取中點的時候寫成a+(b-a)/2;防止溢位
寫法這種比較好
while (x = a[v]) x = mid + 1; //注意看二分的變化
else y = mid;
}
#include#include#include#include#include#includeusing namespace std;
int a[100002] ;
int res[100002];
int bise(int x, int y, int v)
return x;
}int bise1(int x, int y, int v) //二分求上界
else
}cout << p << endl;
res[0] = -1000000;
p = 0;
for (int i = 1; i < count; i++)
else
}cout << p;
return 0;
}
P1020 飛彈攔截
題目描述 某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度...
P1020 飛彈攔截
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...
P1020 飛彈攔截
原題鏈結 貪心 記錄每套系統攔截過的最小高度 新來的飛彈 如果高於所有飛彈的最低高度 那就只能再加一套了嘛 如果低於某些系統的最低高度 那就貪心 把它加到 最低高度最低的一套系統內 include include include include include include include inc...