防御导弹【Java】-动态规划相关知识

这道题老师说涉及动态规划,(动态规划的水题),可是我连动态规划是啥都不懂...因此第一步先查阅相关资料,了解一下动态规划...


#动态规划

动态规划算法的核心就是记住已经解决过的子问题的解

什么样的问题可以考虑使用动态规划解决呢?

::如果一个问题,可以把所有可能的答案穷举出来,并且穷举出来后,发现存在重叠子问题,就可以考虑使用动态规划。

需要联系的动态规划习题类型:最长递增子序列、最小编辑距离、背包问题、凑零钱问题

动态规划算法的两种形式:①自顶向下的备忘录法自底向上

算法-动态规划 Dynamic Programming--从菜鸟到老鸟_HankingHu的博客-CSDN博客_动态规划

#动态规划和贪心算法的区别

转载自:(4条消息) 动态规划和贪心算法的区别_Mingsheng Zhang的博客-CSDN博客_动态规划和贪心算法的区别

联系:
都是分解成子问题来求解,都需要具有最优子结构
所有的贪心问题都可以用动态规划来求解,可以这么说,贪心算法是动态规划的特例。
区别:
1.贪心:每一步的最优解一定包含上一步的最优解,上一步之前的最优解则不作保留;

2.动态规划:全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有的局部最优解 


#题目:防御导弹

题目描述

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

输入描述

最多20个整数,分别表示导弹依次飞来的高度(雷达给出高度数据是不大于30000的正整数)

输出描述

整数M。表示:这套系统最多能拦截 M 枚导弹.

样例输入

300 250 275 252 200 138 245

样例输出

5

#问题分析(个人理解)

因为动态规划,核心思想包括拆分子问题,记住过往,减少重复计算。

就输入案例来看:

a【0】=1,一个导弹拦截数为1

导弹高度300时,300>250,max=a[0]=1; 第2个导弹发射拦截数a【1】=1+1=2

导弹高度250时,300>275,max=a[0]=1; 250<275不满足条件: 第3个导弹发射拦截数a[2]=1+1=2

导弹高度275时,300>252,max=a[0]=1;250<252不满足条件;275>252 max=a[2]=2; a[3]=1+2=3 第4个导弹发射拦截数

导弹高度252时,  300>200,max=a[0]=1,250>200  max=a[1]=2;275>200 max=a[2]=2;252>200 max=a[3]=3; 第5个导弹发射拦截数  a[4]=3+1=4

导弹高度138时, 300>138,max=a[0]=1,,250>138  max=a[1]=2;275>138 max=a[2]=2;252>138 max=a[3]=3; 200>138 max =a[4]=4 第6个导弹发射 拦截数  a[5]=4+1=5

导弹高度245时,300>245,max=a[0]=1,250>245 max=a[1]=2;275>245 max=a[2]=2;252>245 max=a[3]=3;200<245不满足条件;138<245不满足条件 第7个导弹发射 拦截数  a[6]=3+1=4

上面提到:动态规划算法的核心就是记住已经解决过的子问题的解

本题子问题的最优解就是a[i]所对应的每颗导弹发射的时候拦截的最大数量,利用子问题的结果计算一颗颗导弹的最大拦截数(个人见解)


相关题目及答案见:(4条消息) 贪心算法之拦截导弹(C++)_西叶胡杨的博客-CSDN博客


#Java代码

本题即是求动态规划的最长下降子序列:


import java.util.Arrays;
import java.util.Scanner;

//防御导弹
public class FangYuDaoDan {
 public static void main(String [] args){
	 Scanner scanner=new Scanner(System.in);
	 int ddH[]=new int[20];//最多20颗导弹
	 int n=0;//统计导弹数量
	 while(scanner.hasNext()){
		 ddH[n]=scanner.nextInt();
		 n++;
	 }
	 int a[]=new int[n];
	 //用a【】记录下每颗导弹拦截时的最大颗数
	 for(int i=0;i<n-1;i++){
		 a[i]=1;
	 }
	 /*
	  第一颗导弹:初设拦截0颗,判断第一颗导弹拦截最大颗数是否为最优解,并且当前高度>下一颗导弹的高度
	  即可拦截,可拦截一颗,实际能拦截两颗
	  *
	  */	 
	 for(int i=0;i<n-1;i++){
	        int max=0;
	        //找出从0到第i颗中拦截系统标记在a数组中最大的值	      
	        for(int j=0;j<=i;j++){
	            if(a[j]>max&&ddH[j]>=ddH[i+1]){
	                max=a[j];
	            }
	        }
	        //第i+1颗导弹是第max导弹后被拦截,记录第几枚导弹的最大拦截数
	        a[i+1]=max+1;
	    }
	 //给所有拦截数排序
	Arrays.sort(a);
	System.out.println(a[n-1]);
 }
}

 新手上路,边学边记;

这算不算动态规划中的自顶向下的备忘录法?

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小才在学习Lu_lu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值