某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。
輸入飛彈依次飛來的高度(雷達給出的高度資料是≤50000的正整數),計算這套系統最多能攔截多少飛彈,如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
1行,若干個整數(個數≤100000)
2行,每行乙個整數,第乙個數字表示這套系統最多能攔截多少飛彈,第二個數字表示如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
輸入 #1
389 207 155 300 299 170 158 65
輸出 #1
6
2
最多能攔截多少飛彈,其實就是求最長不上公升子串行的長度。用f[i]表示攔截到第i個飛彈時最多攔截的飛彈數。當j第二問則用到狄爾沃斯定理,這個定理正經描述起來比較繁瑣,用通俗的話來講,就是把乙個序列劃分成最少的最長不上公升子串行的個數就等於這個序列的最長上公升子串行的長度。所以第二問最少系統個數就等於飛彈高度的最長上公升子串行的長度。與第一問類似只要改一下判定條件即可。
具體看**注釋。
第一種,常規解法,可得100分
#include
using
namespace std;
int a[
100000
],f[
100000
],g[
100000];
//a存飛彈高度,f[i]表示攔截到第 i個飛彈時最多攔截的飛彈數 ,g[i]表示到第 i個飛彈時高度不下降的最大飛彈數
int max1=
0,min2=0;
//第一問的最大值,第二問的最小值
intmain()
for(
int i=
1;imax1=
max(max1,f[i]);
//更新最終結果
} cout/第一問完成
for(
int i=
1;imin2=
max(min2,g[i]);
//更新最終結果
} cout
}
第二種,二分法優化,可得200分#include
using
namespace std;
int f[
100000
],g[
100000];
//當前攔截飛彈的高度
int a[
100000];
//存飛彈高度
int max1=
1,min2=1;
//第一問的最大值和第二問的最小值
intmain()
n--;//最後乙個輸入為空
//第一問
f[1]=a[1]
;for
(int i=
2;i<=n;i++
)else
//若不能攔截就二分查詢可以替換的位置
f[l]
=a[i];}
} cout/第二問
g[1]=a[1]
;for
(int i=
2;i<=n;i++
)else
g[l]
=a[i];}
} cout
}
動態規劃 飛彈攔截
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷 達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有 的飛彈。輸入資料 第一行為乙個整數 ...
飛彈攔截 動態規劃
描述 某國為了防禦敵國的飛彈襲擊,開發出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲,並觀測到飛彈依次飛來的高度,請計算這套系統最多能攔截多少飛彈。攔截來襲飛彈時,必須按來襲飛彈襲擊的...
動態規劃之飛彈攔截
題目描述 某國為了防禦敵國的飛彈襲擊,發展一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於等於前一發的高度。某天,雷達捕捉到敵國飛彈來襲。由於該系統還在試用階段,所以只用一套系統,因此有可能不能攔截所有的飛彈。輸入資料 第一行輸入測...