题目链接:https://leetcode.cn/problems/climbing-stairs/
思路:物品是楼梯1和2,背包是n求排列数,背包在外物品在内,递推公式dp[i] += dp[i - j]
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n+1];
dp[0] = 1;
for (int i = 0; i <= n; i++) {
for (int j = 1; j <= 2; j++) {
if (j <= i) {
dp[i] += dp[i - j];
}
}
}
return dp[n];
}
}
题目链接:https://leetcode.cn/problems/coin-change/
思路:求所需物品的最少数量,完全背包,定义dp[i]表示背包容量为i时所需物品的最少数量,递推公式dp[i] = dp[i-j] + 1。自然等于放这个物品的前一个位置加1。如dp[5] = dp[5 - 1] + 1 或者 dp [5 - 2] + 1等等,一定得是这些当中最少的那个。故dp[j] = Math.min(dp[j], dp[j-coins[i]] + 1)。最少数量无关排列或者组合。初始化为最大值,dp[0]=0,另外必须得是dp[j-coins[i]] != max时才能进行递推,如果dp[j-coins[i]] == max说明前一个数就没用,现在当前不能在没使用的基础上进行递推。
class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount+1];
int max = Integer.MAX_VALUE;
for (int i = 1; i < dp.length; i++) {
dp[i] = max;
}
for (int i = 0; i < coins.length; i++) {
for (int j = coins[i]; j <= amount; j++) {
if (dp[j-coins[i]] != max) {
dp[j] = Math.min(dp[j], dp[j-coins[i]] + 1);
}
}
}
return dp[amount] == max ? -1 : dp[amount];
}
}
题目链接:https://leetcode.cn/problems/perfect-squares/
思路:和上题基本一样,细节在于完全平方数为i*i
class Solution {
public int numSquares(int n) {
int[] dp = new int[n+1];
int max = Integer.MAX_VALUE;
for (int i = 1; i < dp.length; i++) {
dp[i] = max;
}
for (int i = 1; i*i <= n; i++) {
for (int j = i*i; j <= n; j++) {
dp[j] = Math.min(dp[j], dp[j - i*i] + 1);
}
}
return dp[n];
}
}