class Solution { public int combinationSum4(int[] nums, int target) { int[] dp = new int[target + 1]; //求排列 每一层求得是所有物品刚好凑满i的排列数 每个物品无限使用 dp[0] = 1; for (int i = 0; i <= target; i++) { //背包 for (int j = 0; j < nums.length; j++) { //物品 if (i >= nums[j]) { dp[i] += dp[i - nums[j]]; } } } return dp[target]; } }
//进阶 完全背包 class Solution { public int climbStairs(int n) { int[] dp = new int[n + 1]; //排列问题 [0, 1]无限用 凑i dp[0] = 1; for (int i = 0; i <= n; i++) { for (int j = 1; j <= 2; j++) { if (i >= j) dp[i] += dp[i - j]; } } return dp[n]; } }
class Solution { public int coinChange(int[] coins, int amount) { if (amount == 0) return 0; int[] dp = new int[amount + 1]; Arrays.fill(dp, Integer.MAX_VALUE); //0金额需要0硬币 dp[0] = 0; for (int i = 0; i < coins.length; i++) { for (int j = coins[i]; j <= amount; j++) { //保证前面有解 if (dp[j - coins[i]] == Integer.MAX_VALUE) continue; dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1); } } return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount]; } }
class Solution { public int numSquares(int n) { int[] dp = new int[n + 1]; Arrays.fill(dp, Integer.MAX_VALUE); dp[0] = 0; for (int i = 1; i * i <= n; i++) { //物品 for (int j = i * i; j <= n; j++) { //背包 //保证前面是有有解的 if (dp[j - i * i] == Integer.MAX_VALUE) continue; dp[j] = Math.min(dp[j], dp[j - i * i] + 1); } } return dp[n]; } }
参考:programmercarl.com