递归和动态规划

递归(重点:递推公式+终止条件)

1.找到如何将大问题分解为小问题的规律
2.通过规律写出递推公式
3.通过递归公式的临界点推敲出终止条件
4.将递推公式终止条件翻译成代码

动态规划

1.动态规划法试图只解决每个子问题一次
2.一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。如:每一次迭代过程中,只需要保留之前的两个状态,就可以推到出新的状态。
「动态规划」中包含三个重要的概念:

  • 【最优子结构】
  • 【边界】
  • 【状态转移公式】
    • 在「 爬台阶问题 」中:
      • f(10) = f(9) + f(8) 是【最优子结构】
      • f(1) 与 f(2) 是【边界】
      • f(n) = f(n-1) + f(n-2) 【状态转移公式】

挖金矿

挖金矿

在这里插入图片描述

  • N是金矿数量,W是人数,P[ ]是每个金矿所需人数,G[ ]是每个金矿的价值
  • N=5
  • W=10
  • P[ ]={5,5,3,4,3}
  • G[ ]={400,500,200,300,350}

最优子结构

在这里插入图片描述

边界

  • 当N<=1,W<P[0]时,F(N,W)=0;
  • 当N==1,W>=P[0]时,F(N,W)=G[0];

状态转移方程

  • 当N>1,W<P[N-1]时,F(N,W)=F(N-1,W);
  • 当N>1,W>=P[N-1]时,F(N,W)=MAX(F(N-1,W)F(N-1,W-P[N-1])+G(N-1));

他给的代码运行不出来,还得自己找,不知道是不是因为c和Java的差异问题
在这里插入图片描述

public class testdp {
 static void getMostGold(){
	  int p[] = {5,5,3,4,3};
      int g[]={400,500,200,300,350};
      int n=5,w=10;//w是人数,n是金矿数量
	  int[]preResults=new int[w+1];
	  int[]results=new int[w+1];
	  //填充边界格子的值
	  for(int i=0;i<=w;i++){
		   if(i<p[0]){
		    preResults[i]=0;
		   }else{ 
		    preResults[i]=g[0];
		   }
	  }
  
  //填充其余格子的值,外层循环是金矿数量,内层循环是工人数
	  for(int i=0;i<p.length;i++){
		   for(int j=0;j<=w;j++){
		    if(j-p[i]<0){
		     results[j]=preResults[j];
		    }else  {
		     results[j]=Math.max(preResults[j],preResults[j-(p[i])]+g[i]);
		     
		    }
		   
		   }
	   System.arraycopy(results, 0, preResults, 0, 11);
	   //preResults=Arrays.copyOf(results, results.length);
	  }
	  
	  System.out.println(results[w]);
 
   
 }
  
	 public static void main(String[] args) {
		 getMostGold();
	         
	    }

}
arraycopy
public static void arraycopy(Object src,     //src - 源数组。
                             int srcPos,      //srcPos - 源数组中的起始位置。
                             Object dest,         //dest - 目标数组
                             int destPos, 		//destPos - 目标数据中的起始位置
                             int length)		//length - 要复制的数组元素的数量
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值