题目链接: [Coin Change]
大致题意:
有五种面值的硬币,1分5分10分25分50s分,输入一个钱数s,输出组合方案的数量(s<=250,硬币数量<=100)
解题思路:
dp[i][j]的含义是用j个硬币实现i金额的方案数量,我们令dp[0][0]=1
第一步,只用一分硬币,从dp[0][0]开始推导 ,dp[1][1]是dp[0][0]进行金额+1,硬币数量+1的状态转移,还要考虑dp[1][1]原有的方案数,所以递推式为dp[1][1]=dp[1][1]+dp[0][0],即dp[1][1]=dp[1][1]+dp[1-mon[0]][1-1]
第二步,加上5分硬币,当i>=5时,dp[i][j]=dp[i][j]+dp[i-5][j+1],即dp[i][j]=dp[i][j]+dp[i-mon[1]][j-1]
再加上其他金额的硬币,得出dp[i][j]=dp[i][j]+dp[i-mon[k]][j+1],k=2,3,4…
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int coin = 101;
const int Mon = 251;
int dp[Mon][coin];
int mon[] = { 1,5,10,25,50 };
int ans[Mon];
void init() {
dp[0][0] = 1;
for (int i = 0; i < 5; ++i) {
for (int j = 1; j < coin; ++j) {
for (int k = mon[i]; k < Mon; ++k) {
dp[k][j] += dp[k - mon[i]][j - 1];
}
}
}
}
int main(void)
{
init();
for (int i = 0; i < Mon; ++i) {
for (int j = 0; j < coin; ++j) {
ans[i] += dp[i][j];
}
}
int s;
while (cin >> s) {
cout << ans[s] << endl;
}
return 0;
}