给你一个整数数组 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];
}
};