70. 爬楼梯
之前是一般动规的思路,现在用完全背包的角度来思考一下这道题。
改为:一步一个台阶,两个台阶,三个台阶,.......,直到 m 个台阶。问有多少种不同的方法可以爬到楼顶呢?
这时爬楼梯就变成了一个背包容量为n的完全背包问题,每一步都可以选择从1到m不同的阶数向上爬,并且可以重复选取。原题即为 m = 2 的情况。
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
dp[0] = 1;
int m = 2;
// 先走一步再走两步,和先走两步再走一步,方法是不同的,所以本题实际上是在求排列
// 求排列就是先遍历背包再遍历物品
for(int i = 0; i <= n; i++){
for(int j = 1; j <= m; j++){
if(i - j >= 0)dp[j] += dp[i - j];
}
}
return dp[n];
}
}
322. 零钱兑换
class Solution {
public int coinChange(int[] coins, int amount) {
// dp[i]: 凑成总金额为i所需的最少硬币个数为i
int[] dp = new int[amount + 1];
for(int i = 1; i <= amount; i++)dp[i] = Integer.MAX_VALUE;
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)dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
}
}
return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
}
}
279. 完全平方数
class Solution {
public int numSquares(int n) {
// dp[j]:和为j的完全平方数的最少数量为dp[j]
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++){
dp[j] = Math.min(dp[j - i * i] + 1, dp[j]);
}
}
return dp[n];
}
}