您的位置:首页 > 其它

动态规划-jobdu 1112-最长下降子序列

2017-05-22 09:59 253 查看
题目链接

1. 题目

题目描述:

某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,并观测到导弹依次飞来的高度,请计算这套系统最多能拦截多少导弹。拦截来袭导弹时,必须按来袭导弹袭击的时间顺序,不允许先拦截后面的导弹,再拦截前面的导弹。

输入:

每组输入有两行,

第一行,输入雷达捕捉到的敌国导弹的数量k(k<=25),

第二行,输入k个正整数,表示k枚导弹的高度,按来袭导弹的袭击时间顺序给出,以空格分隔。

输出:

每组输出只有一行,包含一个整数,表示最多能拦截多少枚导弹。

样例输入:

8

300 207 155 300 299 170 158 65

样例输出:

6

说明

样例输出中的6, 对应的就是
(300,300,299,170,158,65)
这个最长下降(严格讲是不上升)子序列.

2. 思路

动态规划

data[i]
表示第i个导弹的高度.

dp[i]
表示前i个数据构成的子串中, 最长下降子序列的长度. 那么状态转移方程就是

dp[i]=dp[j]+1s.t.argmaxjdp[j]且data[j]≥data[i],j∈[0,i)(1)

3. 代码

//jobdu 1112  ac

#include <iostream>
using namespace std;
int data[100];
int dp[100];
int ans;
int number;

void f_init(){
dp[0]=1;
ans=1;  //如果测试数据只有一个数,坑啊!!
}
void f_read(){
int n=number,i=0;
while(n--){
cin>>data[i++];
}
}

void f_calc(){
for(int i=1;i<number;i++){
int tmp=0;
for(int j=i-1;j>=0;j--)
if(data[j]>=data[i] && dp[j]>tmp)
tmp=dp[j];
dp[i]=tmp+1;
if(dp[i]>ans)
ans=dp[i];
}
}

int main( )
{
while(cin>>number){
f_init();
f_read();
f_calc();
cout<<ans<<endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: