518. 零钱兑换 II
思路:
思路和01背包差不多,不同的是在遍历顺序的选择上有所不同。组合问题:先遍历物品,再遍历背包 。 排列问题:先遍历背包,再遍历物品。这种分配不是绝对的,但在一般情况下是最简单的,逻辑简单的。
此题是一个组合问题,所以选择先遍历物品,再遍历背包
代码:
class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<uint64_t> dp(amount+1,0);
//dp数组的初始化
dp[0] = 1;
for(int i =0;i<coins.size();i++)
{
for(int j = coins[i];j<=amount;j++)
{
dp[j] +=dp[j-coins[i]];
}
}
return dp[amount];
}
};
遇到的问题:
1.对于遍历顺序的不同、
377. 组合总和 Ⅳ
思路:
此题是一个排列问题,所以在遍历顺序时,选择先遍历背包,再遍历物品
代码:
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + 1, 0);
dp[0] = 1;
for (int i = 0; i <= target; i++) { // 遍历背包
for (int j = 0; j < nums.size(); j++) { // 遍历物品
if (i - nums[j] >= 0 && dp[i] < INT_MAX - dp[i - nums[j]]) {
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
}
};
遇到的问题:
对于遍历顺序的理解
57. 爬楼梯
思路:
排列问题,遍历顺序选择先遍历背包,再遍历物品
代码:
def climbing_stairs(n,m):
dp = [0]*(n+1) # 背包总容量
dp[0] = 1
# 排列题,注意循环顺序,背包在外物品在内
for j in range(1,n+1):
for i in range(1,m+1):
if j>=i:
dp[j] += dp[j-i] # 这里i就是重量而非index
return dp[n]
if __name__ == '__main__':
n,m = list(map(int,input().split(' ')))
print(climbing_stairs(n,m))
遇到的问题:
对于遍历顺序的理解