某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。
但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。
某天,雷達捕捉到敵國的飛彈來襲。
由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。
輸入飛彈依次飛來的高度(雷達給出的高度資料是不大於 30000
30000
3000
0 的正整數,飛彈數不超過 1000
1000
1000
),計算這套系統最多能攔截多少飛彈,如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
輸入格式
共一行,輸入飛彈依次飛來的高度。
輸出格式
第一行包含乙個整數,表示最多能攔截的飛彈數。
第二行包含乙個整數,表示要攔截所有飛彈最少要配備的系統數。
資料範圍
雷達給出的高度資料是不大於 30000
30000
3000
0 的正整數,飛彈數不超過 1000
1000
1000
。輸入樣例:
389 207 155 300 299 170 158 65
輸出樣例:
6
2
由條件1可知,「第一發炮彈可以選任意高度,後面的炮彈不能高於前一發的高度:」,說明我們要找乙個下降子串行。
由目標可知,第一問是要找乙個最長下降子串行,直接求反向的最長上公升子串行即可,具體解法可見acwing895_最長上公升子串行。
對於第二問,有如下分析:
首先對於每乙個數,我們可以將其接在乙個現有的子串行之後,也可以建立乙個新的子串行。
當我們將其接到乙個子串行後面時,一定是所有滿足要求子串行的最小的那乙個(就是最後乙個數是滿足要求的最小的那乙個)。
所以我們可以通過貪心法解決第二問。
貪心流程:
從前往後掃瞄每乙個數,對於每個數:
如果現有子串行的結尾都小於當前數,則建立新的子串行。
將當前數放到結尾大於等於他的最小的子串行後面。
#include #include using namespace std;
const int n = 1010;
int n, cnt;
int a[n];
int f[n], g[n];
int main()
printf("%d\n", res);
for (int i = 0; i < n; i ++ )
printf("%d\n", cnt);
return 0;
}
o(n
2)
o(n^2)
o(n2
)
AcWing 1010 攔截飛彈
解題思路 這道題目的第乙個問題就是求最長下降子串行,直接用乙個dp就可以了 而對於第二個問題,問最少用多少個系統可以攔截所有的飛彈,我剛還是的思路是不斷地去求最長下降子串行,指導飛彈被去完為止,但是後來我找到了這個思路的乙個bug,然後想我們可以直接維護乙個陣列,陣列裡面就是各自系統中最小的飛彈的高...
Acwing 1010 攔截飛彈 單調子串行
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...
1010 攔截飛彈
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...