leetcode518. 零钱兑换 II
思路
明确dp[i][j]数组的意义:前i种,总金额为j的组合数
状态转移方程:第i种选或不选共两种,dp[i][j] = dp[i-1][j]+dp[i][j-coins[i-1]],但要保证j-coins[i-1]大于等于0,否则为dp[i][j] = dp[i-1][j]。
边界条件:dp[0][j]为0,dp[i][0]为1。
目标结果:dp[n][amount]
代码
class Solution { public: int change(int amount, vector<int>& coins) { vector<int >dp(amount+1,0); dp[0] = 1; for (auto coin :coins) //枚举每个硬币数量 { for (int j =coin;j<amount+1;j++) // { dp[j] = dp[j] + dp[j-coin]; } } return dp[amount]; } };
代码2:
class Solution { public: int change(int amount, vector<int>& coins) { // 完全背包问题:动态规划 if(amount < 0) // coins 为空,amount为 0 时,算一种情况; return 0; int * dp = new int[amount + 1](); dp[0] = 1; for(int i = 0; i < coins.size(); i++) for(int j = coins[i]; j <= amount; j++) dp[j] = dp[j] + dp[j - coins[i]]; // 相当于叠加了前 i 个***,在总和价值为 j 时的可能数; int res = dp[amount]; delete[] dp; return res; } };
以大多数人努力程度之低,根本轮不到去拼天赋~