动态规划 导弹拦截

2018-06-17 22:52:09来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

题意:一种导弹拦截系统的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉

到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。输入导弹依次飞来的高

度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统?

 第一问思路非常简单,不断改变终止点的位置,更新dp数组。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int dp[1010],a[1010];
int main()
{
    int cases;
    cin>>cases;
    while(cases--)
    {
        memset(dp,0,sizeof(dp));
        int n;
        cin>>n;
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        dp[0]=1;//最小子序列一定是1,没有更小的了
        for(int i=1;i<n;i++)
        for(int j=0;j<i;j++)
        if(a[i]<a[j]&&dp[j]+1>dp[i]){dp[i]=dp[j]+1;}
        cout<<*max_element(dp,dp+n)<<endl;
    }
}

第二问难度比较大

我们把第二问的问题抽象出来,那就是:把一个数列划分成最少的最长不升子序列。

Dilworth定理

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int dp[1010],a[1010];
int main()
{
    int cases;
    cin>>cases;
    while(cases--)
    {
        int n;
        cin>>n;
        fill(dp,dp+n,1);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        dp[0]=1;//最小子序列一定是1,没有更小的了
        for(int i=1;i<n;i++)
        for(int j=0;j<i;j++)
        if(a[j]<a[i]&&dp[j]+1>dp[i]){dp[i]=dp[j]+1;}//changes;
        cout<<*max_element(dp,dp+n)<<endl;
    }
}

思路就是从头录到tail,能摁在一块的安一快。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:1722 最优乘车 1997年NOI全国竞赛

下一篇:伸展树(Splay树)的简要操作