硬币找零,其本质就是组合问题,所以在写的时候要使 coin 成严格的非递减序列
具体的题号不记得了,当时用的不是记忆化搜索的方式:
#include <stdio.h> #include <string.h> int step[18] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289}; int main() { int money, ans; int dp[305]; int i, j, index; index = 1; while(scanf("%d", &money), money != 0) { memset(dp, 0, sizeof(dp)); dp[1] = 1; for(index = 1; index < 18; index++) { for(i = 1; i <= money+1; i++) { if(i >= step[index]) { dp[i] = dp[i-step[index]] + dp[i]; } } } for(i = 1; i < money+2; i++) { printf("%d ", dp[i]); } printf("\n%d\n", dp[money+1]); } return 0; }
记忆化搜索的代码:
#include<stdio.h> #include<string.h> #define maxn 7500 const long coin[]={0,1,5,10,25,50}; long n,d[maxn][6]; long dp(long s,long k) { if(d[s][k]!=-1) return d[s][k]; d[s][k]=0; for(long i=k;i<=5&&s>=coin[i];i++) d[s][k]+=dp(s-coin[i],i); return d[s][k]; } int main() { memset(d,-1,sizeof(d)); for(long i=0;i<=5;i++) d[0][i]=1; while(scanf("%ld",&n)==1) printf("%ld\n",dp(n,1)); return 0; }