动态规划
形式:求最值问题!!!
核心:穷举;状态转移方程
最优子结构,是否能够通过子问题的最值得到原问题的最值。
基本思路: 暴力穷举-------> 避免重复计算--------->优化空间复杂度;
时间复杂度计算
递归算法的时间复杂度怎么计算?就是用子问题个数乘以解决一个子问题需要的时间。
例题
零钱兑换
1.暴力解法:
class Solution { // 暴力解法,时间会超;
public int coinChange(int[] coins, int amount) {
//动态规划的经典
return dp(coins,amount);
}
public int dp(int[] arr,int n){
//base case
if(n==0) return 0;
if(n<0) return -1;
int res =Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
int sub = dp(arr,n-arr[i]);
if(sub ==-1) continue;
res = Math.min(res,sub+1);
}
return res==Integer.MAX_VALUE?-1:res;
}
}
2.避免重复计算
class Solution {
int[] memo;
public int coinChange(int[] coins, int amount) {
//动态规划的经典
//状态转移方程?
memo =new int[amount+1];
Arrays.fill(memo,-1000);
return dp(coins,amount);
}
public int dp(int[] arr,int n){
if(n==0) return 0;
if(n<0) return -1;
//base case
if(memo[n]!=-1000)
return memo[n];
int res =Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
int sub = dp(arr,n-arr[i]);
if(sub ==-1) continue;
res = Math.min(res,sub+1);
}
memo[n] =(res==Integer.MAX_VALUE)?-1:res;
return memo[n];
}
}