拦截导弹

这是一道经典的动态规划的题目

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000 的正整数),计算这套系统最多能拦截多少导弹,并依次输出被拦截的导弹飞来时候的高度。
样例:
INPUT
389 207 155 300 299 170 158 65
OUTPUT
6//最多能拦截的导弹数

389 300 299 170 158 65


最长递增子序列是动态规划中的经典问题之一,我们可以通过这一道题目来练习一维动态规划题目的解题思路。
首先如果我们不知道这道题目可以用动态规划去解,用一些常规的思路去解的话,应该怎么做。

brute force(蛮力法):当然是DFS了,遍历所有可能的递减序列。时间复杂度很高,约为2**n。
寻找规律法:看来看去,似乎没有什么规律可言,反倒是一环套一环,给人很复杂的感觉。


动态规划:
按照我在解动态规划题目的步骤中给出的,判断一个题目是否能用动态规划去做,要看看其是否拥有最优子策略,是否拥有无后效性,或者是否拥有重叠计算的问题。

子问题:假设{a1,a2,...an}为这个序列
1.首先我们需要定义这个问题:设f(n)为{a1,a2,...an}的最优解,那么其子问题则为f(i)(1<=i<=n),f(i)表示{a1,a2,...ai}的解,也就是这个序列的最长递减序列的长度

2.其次我们需要想想如何通过这个最优子问题去构建这个问题,也就是写出递归表达式,很明显,f(i)跟f(1),f(2),...f(i-1)有关。
于是有递归表达式f(i)=max{1,f(j)+1|aj<ai && 1<=j<i},这个式子比较难看懂,解释一下:f(i)是下列取值中的最大值 1,f(j)+1{如果 aj<ai && 1<=j<i 则f(j)+1,如果aj>=ai,则直接为一},
3.自底向上计算
这里描述的是递减序列,非递增序列的原理与上面的类似

下面给出代码:

int SequenceL(int *array, int n){
    int *temp=new int[n];
    memset(temp,0,sizeof(int)*n);
    temp[0]=1;
    int max=1;
    for(int i=1 ; i<n ; i++){
        max=1;
        for(int j=i-1 ; j>=0 ; j--){
            if(array[j]>=array[i] && temp[j]+1>max)
                max=temp[j]+1;
        }
        temp[i]=max;
    }
    delete temp;
    return max;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值