资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入格式
一行,为导弹依次飞来的高度
输出格式
两行,分别是最多能拦截的导弹数与要拦截所有导弹最少要配备的系统数
样例输入
389 207 155 300 299 170 158 65
样例输出
6
2
/* 解题思路: 递归: h为导弹高度 共有h.size()个导弹,对于更低的导弹有两种选择:拦截或不拦截 设OPT(i)为前i个导弹的最优拦截方案,共可以拦截n枚 设last(i)为上一个比第i个导弹高的导弹编号 则有:OPT(i)= 拦截: OPT(last(i))+1 不拦截:OPT(i-1) 递归结束条件:if(i==0) OPT(i)=1; else if(i==1) if(h[i]<=h[i-1]) OPT(i-1)+1; else OPT(i)=OPT(i-1); 对递归进行剪枝→动态规划: 使用dp1[]记录每次OPT(i++)的结果 若上一个导弹的高度大于等于当前导弹且如若拦截则比上一个最优解更好 则 dp1[i]=dp1[j]+1; dp2[]同理 */ #include <iostream> #include <vector> using namespace std; int main(){ vector<int>h; int i,j,ans=0,cnt=0; while(cin.peek()!='\n'){ cin>>i; h.push_back(i); } //for(i=0;i<h.size();i++) cout<<h[i]<<endl; int dp1[h.size()]={0},dp2[h.size()]={0}; for(i=0;i<h.size();i++){ dp1[i]=dp2[i]=1; for(j=0;j<i;j++){ if(h[j]>=h[i]){ if(dp1[i]<dp1[j]+1) dp1[i]=dp1[j]+1; } else{ if(dp2[i]<dp2[j]+1) dp2[i]=dp2[j]+1; } } for(j=0;j<h.size();j++) cout<<dp1[j]<<" "<<dp2[j]<<endl; cout<<endl; if(ans<dp1[i]) ans=dp1[i]; if(cnt<dp2[i]) cnt=dp2[i]; } cout<<ans<<endl<<cnt; }
本人小白一枚,如有差错,望大佬能指出
谢谢阅读;