构建动态规划表步骤:
1.递归版本
2.记忆化搜索版本
3.严格表结构
<1>找出变化的参数及参数变化的范围,声明dp表
<2>初始化表项
<3>确认最终需要的返回值在表中的位置
<4>建立依赖关系和遍历顺序
<5>优化遍历方法
动态规划经典问题:
零钱兑换:给定一个面值数组coins[],每种面值可以使用无限多次,给定一个整型aim,问将aim完全找开有多少种方法
递归版本
// 给定一个面值数组arr,数组中每个面值都可以无限次被选择,问将aim找开有多少种方法
public int change(int[] arr, int rest, int index){
if(index==arr.length) return 0;
if(rest==0) return 1;
int ways = 0;
for (int i = 0; rest-arr[index]*i>=0 ; i++) {
ways+=change(arr,rest-arr[index]*i,index+1);
}
return ways;
}
严格表版本
public int change(int amount, int[] coins) {
int N = coins.length;
int[][] dp = new int[N + 1][amount + 1];
dp[N][0] = 1;
for (int i = N-1; i >=0 ; i--) {
for (int j = 0; j <=amount; j++) {
int ways = 0;
for (int k = 0; coins[i]*k<=j; k++) {
ways = dp[i+1][j];
if(j-coins[i]>=0){
ways+=dp[i][j-coins[i]];
}
}
dp[i][j] = ways;
}
}
return dp[0][amount];
}