1044 拦截导弹——http://codevs.cn/problem/1044/
第一部分:題目
題目描述?Description? ? 某國為了防御敵國的導彈襲擊,發展出一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以后每一發炮彈都不能高于前一發的高度。某天,雷達捕捉到敵國的導彈來襲。由于該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的導彈。
??
輸入描述?Input Description輸入導彈依次飛來的高度(雷達給出的高度數據是不大于30000的正整數)
??
輸出描述?Output Description輸出這套系統最多能攔截多少導彈,如果要攔截所有導彈最少要配備多少套這種導彈攔截系統。
樣例輸入?Sample Input389 207 155 300 299 170 158 65?
樣例輸出?Sample Output6
2
數據范圍及提示?Data Size & Hint導彈的高度<=30000,導彈個數<=20
第二部分:思路
需要解決兩個問題:1,一套系統最多攔截多少導彈?2,要攔截所有導彈最少需要多少系統?
問題1:動態規劃:主要是確定攔截哪些導彈。也就是求數列中的最長遞減序列。從最后一個數開始,統計以每個數為首的遞減序列的長度,取最長的即可。
問題2:貪心:就是盡可能每次攔截最多導彈??梢钥闯鼍褪敲看伟褑栴}1的結果即最長序列中的導彈全攔截了,直到所有導彈都被攔截為止。這里怎么表示導彈被攔截了呢:把被攔截的導彈的遞減序列長度置為0即可。然后需要從新進行遞減序列長度計算。
第三部分:代碼
#include<stdio.h> int s[20][2],len=0;//存儲導彈高度及以其為首的最長遞減序列長度 int acount()//計算遞減序列長度并返回最大值 {int Max=0,j,i;for(i=len-2;i>=0;i--)//從最后一個數開始計算 {int max=0;for(j=i+1;j<len;j++){//注意:s[j][1]該值為0表示導彈被攔截了,就pass。 if(s[j][1]>0&&s[i][0]>s[j][0]&&max<s[j][1]) {max=s[j][1];}}if(s[i][1]>0){s[i][1]=max+1;}if(Max<s[i][1])//尋找最大值 {Max=s[i][1];}}return Max; } int main() {int height;while(scanf("%d",&height)!=EOF){s[len][0]=height;s[len++][1]=1;//初始化每個導彈的最長遞減序列長度為1 }int i,j;int Max=acount();//第一次系統能夠攔截導彈最大值 int max=acount();//每次能夠攔截最大值 int count=0;//統計需要至少多少系統 while(max>0)//當前有導彈未被攔截就進行攔截操作 {count++;//每次攔截的都是攔截最多導彈:可以想象,依次攔截的導彈的序列長度//是遞減的。 for(i=0;i<len;i++){if(s[i][1]==max&&max>0){s[i][1]=0;max--;}if(max==0)//當前攔截結束 {break;}}max=acount();//需要重新計算序列長度以及當前剩下所有導彈的最長遞減序列 }printf("%d\n%d\n",Max,count);return 0; }?
轉載于:https://www.cnblogs.com/xiangguoguo/p/5386544.html
總結
以上是生活随笔為你收集整理的1044 拦截导弹——http://codevs.cn/problem/1044/的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle database serv
- 下一篇: [Java拾遗三]JavaWeb基础之S