Problem Description:
假设一堆由1分、2分、5分组成的n个硬币总面值为m分,求一共有多少种可能的组合方式(某种面值的硬币可以数量可以为0)。
Input:
输入数据第一行有一个正整数T,表示有T组测试数据;
接下来的T行,每行有两个数n,m,n和m的含义同上。
Output:
对于每组测试数据,请输出可能的组合方式数;
每组输出占一行。
Sample Input:
2
3 5
4 8
Sample Output:
1
2
AC Code(方法1:暴力):
#include<stdio.h> #include<string.h> #include<stdlib.h> int main() { int t,ans,n,m; scanf("%d",&t); while(t--) { ans=0; scanf("%d %d",&n,&m); for(int i=0;i<=m/1;i++) for(int j=0;j<=m/2;j++) for(int k=0;k<=m/5;k++) if((i+j+k)==n&&(i*1+j*2+k*5)==m) ans++; printf("%d\n",ans); } return 0; }
AC Code(方法2:DP):
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=1001; int dp[N][N]; int num[4]={0,1,2,5};//分别代表几种面值的硬币 int main() { int t,n,m; cin>>t; while(t--) { cin>>n>>m; memset(dp,0,sizeof(dp));//清零 dp[0][0]=1;//第一个值为1,表示用0个硬币构成面值为0的方案仅有一个 for(int i=1;i<=3;i++)//三种硬币(1,2,5) { for(int j=1;j<=n;j++)//n个硬币 { for(int k=num[i];k<=m;k++)//每种硬币的面值 { dp[j][k]+=dp[j-1][k-num[i]];//硬币数量减1,同时减去对应硬币的面值 } } } cout<<dp[n][m]<<endl; } return 0; }