题意:
有1,5,15,25,50五种货币,问n元最多有多少种兑换方法
思路:
dp[i]表示i钱最多的兑换方法,dp[i+num[k]] += dp[i]。此时要注意dp的转移顺序。需要仔细理解。
(一开始用母函数做,果断超时了。也可以dfs记忆化搜索)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstdlib> #include <cstring> const int MAXN = 8000; long long int dp[MAXN]; int a[5] = {1, 5, 10, 25, 50}; int main() { int n; while (scanf("%d", &n) != EOF) { memset(dp, 0, sizeof(dp)); dp[0] = 1; for (int i = 0; i < 5; ++i) for (int j = 0; j <= n; ++j) dp[j+a[i]] += dp[j]; printf("%lld\n", dp[n]); } return 0; }
母函数(超时):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstdlib> #include <cstring> const int MAXN = 8000; long long int c1[MAXN], c2[MAXN]; int main() { int n; while (scanf("%d", &n) != EOF) { for (int i = 0; i <= n; ++i) c1[i] = 1, c2[i] = 0; int num[5] = {5, 10, 25, 50}; for (int i = 0; i < 4; ++i) { for (int j = 0; j <= n; ++j) for (int k = 0; k + j <= n; k += num[i]) c2[k+j] += c1[j]; for (int j = 0; j <= n; ++j) c1[j] = c2[j], c2[j] = 0; } printf("%lld\n", c1[n]); } return 0; }