Making N Dollars 拼凑面值N
题意:有面值为1~100的硬币,每种面值不限个数,求有多少种解法
思路:用data[num][coin]记录用硬币1~coin拼面额为num的价值所需的硬币数。从大面额开始,最多使用step=num/coin枚,最少使用0枚,则排除一种硬币。
该大面额硬币使用几次对应几种需递归处理的情况。
边界: 只有面额为1的硬币则所有面额的拼法都只有一种;无论多少种硬币,拼凑价值为0的面额也只有一种。
自底向上写法:
1 #include <iostream> 2 using namespace std; 3 int n,k,t; 4 int ways[101][1001]={0}; 5 int main(){ 6 cin>>t; 7 for(int j=0;j<=1000;j++)ways[1][j]=1; 8 for(int i=0;i<=100;i++)ways[i][0]=1; 9 for(int i=2;i<=100;i++) 10 for(int j=1;j<=1000;j++) 11 for(int k=0;k*i<=j;k++) 12 ways[i][j]=(ways[i][j]+ways[i-1][j-k*i])%inf; 13 while(t--){ 14 cin>>n>>k; 15 cout<<ways[k][n]<<endl; 16 } 17 return 0; 18 }
自上而下的递归写法:
1 //Making N Dollars 2 #include <stdio.h> 3 #define inf 100000000 4 int T, N, K, data[1005][105]; 5 6 int toBottom(int num,int coin){ 7 if(data[num][coin]>0) 8 return data[num][coin]; 9 int step=num/coin,sum=0; 10 for(int i=step;i>=0;i--){ 11 sum=(sum+toBottom(num-i*coin,coin-1))%inf; 12 } 13 data[num][coin]=sum; 14 return sum; 15 } 16 17 int main(void){ 18 freopen("input.txt", "r", stdin);. 19 setbuf(stdout, NULL); 20 scanf("%d", &T); 21 for(int i=1;i<1005;i++)data[i][1]=1; 22 for(int i=1;i<105;i++)data[0][i]=1; 23 for(int test_case = 1; test_case <= T; test_case++){ 24 scanf("%d %d", &N,&K); 25 printf("Case #%d\n%d\n", test_case, toBottom(N,K)); 26 } 27 return 0; 28 }