总链接:第九章 动态规划part07
70. 爬楼梯 (进阶)
链接:代码随想录
class Solution { /* 用完全背包的思路想.可以有多个物品(1、2)则完全背包 1 2 和2 1 不同,故是排列问题。先背包容量再物品 物品为: 0 1 2 3 4.。。n 1 2 */ public: int climbStairs(int n) { vector<int>dp(n+1,0); vector<int>w;//相当于物品 w.push_back(1); w.push_back(2); dp[0]=1; for(int j=0;j<=n;j++) { for(int i=0;i<2;i++) { if(j>=w[i]) { dp[j]+=dp[j-w[i]]; } } } return dp[n]; } };
322. 零钱兑换
链接:代码随想录
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
思路基本没问题,有些约束条件不知道为什么会加
class Solution { /* 零钱兑换是经典的动态规划问题 每种硬币的数量是无限的---------------完全背包 5+5+1 和1+5+5 没什么区别,所以是组合问题 组合问题先遍历物品再遍历背包容量 dp[j]代表凑成总金额j所需的 最少的硬币个数 递推公式: dp[j]=min(dp[j-nums[i]]+1,dp[j]); 初始值: dp[0]=1; dp[1]=1; dp[2]=min(dp[]) 最少硬币个数,物品个数问题 0 1 2 3 4 5 6 7 8 9 10 11 1 0 1 2 3 4 2 0 1 1 5 */ public: int coinChange(vector<int>& coins, int amount) { vector<int>dp(amount+1,INT_MAX); dp[0]=0; for(int i=0;i<coins.size();i++) { for(int j=coins[i];j<=amount;j++) { if (dp[j - coins[i]] != INT_MAX) { // 如果dp[j - coins[i]]是初始值则跳过 { dp[j]=min(dp[j-coins[i]]+1,dp[j]); } } } if (dp[amount] == INT_MAX) return -1;//边界条件 return dp[amount]; } };
这俩条件没写出来报错了
279.完全平方数
本题 和 322. 零钱兑换 基本是一样的,大家先自己尝试做一做
链接:代码随想录
视频讲解:动态规划之完全背包,换汤不换药!| LeetCode:279.完全平方数_哔哩哔哩_bilibili
class Solution { /* 重叠子问题,可重复使用,完全背包问题 组合?排列,因为没有要求位置上的区别,所以是组合问题,先遍历物品再遍历背包 dp[j] 是 和为 j 的完全平方数的最少数量 w[i]相当于物品,要找到n以内所有完全平方数作为物品重量 dp[j]=min(dp[j-w[i]]+1,dp[j]); */ public: int numSquares(int n) { vector<int>w; for(int i=1;i*i<=n;i++) { w.push_back(i*i); } vector<int>dp(n+1,INT_MAX); dp[0]=0; dp[1]=1; for(int i=0;i<w.size();i++) { for(int j=w[i];j<=n;j++) { if(dp[j-w[i]]!=INT_MAX) { dp[j]=min(dp[j-w[i]]+1,dp[j]); } } } if(dp[n]==INT_MAX) { return -1; } return dp[n]; } };