1.计数
2.最大最小值
3.存在性
1.确定状态:确定最优策略最后一步,确定子问题
2.转移方程:根据子问题
3.初始条件和边界情况
4.计算顺序:利用之前的计算结果
常见动态规划类型:
1.坐标型 2.序列型 3.划分型 4.区间型 5.背包型 6.最长序列 7.博弈性 8.综合型
669. Coin Change
思路:属于求最值情况
https://www.lintcode.com/problem/coin-change/description?_from=ladder&&fromId=16

public class Solution { /** * @param coins: a list of integer * @param amount: a total amount of money amount * @return: the fewest number of coins that you need to make up */ public int coinChange(int[] coins, int amount) { // write your code here if(coins==null || coins.length ==0){ return 0; } int[] f = new int[amount+1]; f[0]=0; //从i=1开始迭代,从0开始迭代是错误的 for(int i=1;i<=amount;i++){ f[i] = Integer.MAX_VALUE; for(int j =0;j<coins.length;j++){ if(i>=coins[j] && f[i-coins[j]]!=Integer.MAX_VALUE){ f[i] = Math.min(f[i],f[i-coins[j]]+1); } } } if(f[amount]==Integer.MAX_VALUE){ return -1; } return f[amount]; } }
191. Maximum Product Subarray
思路:因为有负数的情况,需要两个状态方程分别记录过程中的最大值,最小值
https://www.lintcode.com/problem/maximum-product-subarray/description?_from=ladder&&fromId=16

public class Solution { /** * @param nums: An array of integers * @return: An integer */ public int maxProduct(int[] nums) { // write your code here int[] f = new int[nums.length]; int[] g = new int[nums.length]; f[0] = nums[0]; //最大值 g[0] = nums[0]; //最小值 int max = Integer.MIN_VALUE; for(int i=1;i<nums.length;i++){ f[i]=Math.max(nums[i],Math.max(f[i-1]*nums[i],g[i-1]*nums[i])); g[i]=Math.min(nums[i],Math.min(f[i-1]*nums[i],g[i-1]*nums[i])); } for(int i=0;i<nums.length;i++){ max = Math.max(f[i],max); } return max; } }
来源:https://www.cnblogs.com/lizzyluvcoding/p/10795551.html