某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。
但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。
某天,雷達捕捉到敵國的飛彈來襲。
由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。
輸入飛彈依次飛來的高度(雷達給出的高度資料是不大於30000的正整數,飛彈數不超過1000),計算這套系統最多能攔截多少飛彈,如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
輸入格式
共一行,輸入飛彈依次飛來的高度。
輸出格式
第一行包含乙個整數,表示最多能攔截的飛彈數。
第二行包含乙個整數,表示要攔截所有飛彈最少要配備的系統數。
輸入樣例:
389 207 155 300 299 170 158 65
輸出樣例:6
分析:這道題的題意就是,找單調下降最長的長度,然後如果第一遍找不完,再從剩下的飛彈高度裡邊在進找,直到找到所有嚴格單調下降的飛彈高度,並統計找的次數2
換句人話--->用多少個單調下降子串行把完整的序列覆蓋掉
貪心的流程:
從前往後掃瞄每個數:
case 1:如果現有的子串行都小於當前的數,就建立乙個新的子串行
case 2:將當前數放在大於等於它的最小子序列後面
這個g陣列 就相當於我們的子串行末尾的數,他要保證單調上公升,而我們的a就是當前子串行末尾的大於等於x的最小值,也就是將x放在了子串行結尾大於等於x的子串行的後面,也就是a的後邊;
這道題如果深挖的化有乙個反鏈的叫做dailworth定理,有興趣的可以了解下,在這裡我就不贅述了。
這裡的輸入比較特別可以參考下c++的stringstream
具體詳解**:
1 #include2 #include34using
namespace
std;
5const
int n = 1010;6
intn;
7int
q[n];
8int
f[n],g[n];910
intmain()
19 cout << res <
2021
//用g陣列儲存我們當前現有的所有的子串行
22//
用cnt表示我們當前現有子串行的個數
23int cnt = 0;24
//從前往後貪心一遍
25for(int i = 0;i < n;i++)
3435 cout <
3637 }
AcWing 1010 攔截飛彈
解題思路 這道題目的第乙個問題就是求最長下降子串行,直接用乙個dp就可以了 而對於第二個問題,問最少用多少個系統可以攔截所有的飛彈,我剛還是的思路是不斷地去求最長下降子串行,指導飛彈被去完為止,但是後來我找到了這個思路的乙個bug,然後想我們可以直接維護乙個陣列,陣列裡面就是各自系統中最小的飛彈的高...
AcWing1010 攔截飛彈
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...
攔截飛彈 vip
描述 某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷...