518. 零钱兑换 II
给你一个整数数组 coins
表示不同面额的硬币,另给一个整数 amount
表示总金额。
请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0
。
假设每一种面额的硬币有无限个。
题目数据保证结果符合 32 位带符号整数。
思路:
对一堆数字中选取某几个,且每个数字可以重复出现,因此是完全背包问题。
dp[i][j]表示前i个字符组合是j的所有组合数。
dp[i][j]=dp[i-1][j]+dp[i][j-coins[i]]。(此处用+的原因是要求的是所有可能的组合数)
初始化:
i为0的时候,仅有j同样为0才有可能有组合数,因此其余均为0.
当j为0的时候,对i任意取值,都存在一个数都不取结果为0的情况,因此dp[i][0]为1.
class Solution {
public:int change(int amount, vector<int>& coins) {int n=coins.size();int INF=0x3f3f3f3f;vector<vector<int>>dp(n+1,vector<int>(amount+1,0));for(int i=0;i<=n;i++){dp[i][0]=1;}coins.insert(coins.begin(),0);for(int i=1;i<=n;i++){for(int j=1;j<=amount;j++){dp[i][j]=dp[i-1][j];if(j-coins[i]>=0){// cout<<i<<j-coins[i]<<" ||";dp[i][j]+=dp[i][j-coins[i]];}}}return dp[n][amount]==INF?0:dp[n][amount];}};