(详解!)简单动态规划实例——导弹拦截

问题描述
  某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
  输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入格式
  一行,为导弹依次飞来的高度
输出格式
  两行,分别是最多能拦截的导弹数与要拦截所有导弹最少要配备的系统数
样例输入
389 207 155 300 299 170 158 65
样例输出
6
2

动态规划

这题是典型的动态规划问题,对于动态规划,我们需要开辟一个数组来存放每一步的最优解,用来找到整体的最优解。
一个简单的例子如下:
求解右式:1+1+1=?
毫无疑问结果是3,对于该式我们的解法其实就是数有多少个1。
接下来,我们在左式后再加上一个"+1",结果又是多少呢?答案很明显是4。我们是如何得出这个4的呢?实际的计算过程就是将上一步得出的结果直接加上了1。每一步的结果我们实际上都有作一个“保存”,下一步便可依此找寻最优解。这便是动态规划的基本思想。

再来看这道题。需要输出的结果有两个,一个是一次最多能拦截的导弹数(最长下降子序列),和拦截所有导弹需要的系统个数(最长上升子序列)。这两个结果在实际求解中是一组互逆的运算,针对其中一个问题求出了结果,另一个也就迎刃而解了。

那么现在主要分析能拦截到的最大导弹数量。面对每一个导弹飞来的高度,如果当前高度比前一个高度低,那么可以拦截的导弹数+1,否则不作变换。对于每一步的结果dp[]我们初始化为1,因为每个导弹都可以对自身高度的导弹进行拦截。

   dp : 1   1   1   1   1   1   1   1

整个的过程如下,其中Height为每个导弹飞来的高度,dp为每个导弹飞来后得出的当前最优解。

Height:389 207 155 300 299 170 158 65
   dp : 1   2   3   2   3   4   5   6

所以当当前导弹高度小于之前的导弹高度(即定义循环变量i,遍历所有导弹高度,循环变量j,遍历已经飞过导弹高度。是否满足Height[i]<=Height[j] ),且可以拦截的导弹数量也小于之前导弹的数量时(dp[i]<=dp[j]),满足条件,可以拦截。那么对应的dp[i]+1。
由此我们可以推出它的状态转移方程:
dp[i]=max(dp[i],dp[j]+1)
那么不难写出核心代码如下:

		for(int i=0;i<n;i++) {
   
   //n为输入的导弹数量
			for(int j=0;j<i;j++<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demonslzh6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值