hdu 2566 统计硬币
http://acm.hdu.edu.cn/showproblem.php?pid=2566
假设一堆由1分、2分、5分组成的n个硬币总面值为m分,求一共有多少种可能的组合方式(某种面值的硬币可以数量可以为0)。
输入数据第一行有一个正整数T,表示有T组测试数据;
接下来的T行,每行有两个数n,m,n和m的含义同上。
接下来的T行,每行有两个数n,m,n和m的含义同上。
对于每组测试数据,请输出可能的组合方式数;
每组输出占一行。
每组输出占一行。
Sample Input
2
3 5
4 8
Sample Output
1
2
【题解】: 这里没有给出n,m的范围,建议使用第三种【code3】方式解
【code1】:暴力O(N*N)
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 5 using namespace std; 6 7 int main() 8 { 9 int t; 10 scanf("%d",&t); 11 while(t--) 12 { 13 int i,n,m,j; 14 scanf("%d%d",&n,&m); 15 int cnt=0; 16 for(i=0;i<=m/5;i++) 17 { 18 for(j=0;j<=m/2;j++) 19 { 20 if(n-i-j+j*2+i*5==m&&n-i-j>=0) 21 { 22 cnt++; 23 } 24 } 25 } 26 printf("%d\n",cnt); 27 } 28 return 0; 29 }
【code2】:暴力 O(N)
似乎只要1、2、5,硬币的个数中的一个固定了,另外两个也就一定
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 5 using namespace std; 6 7 int main() 8 { 9 int t; 10 scanf("%d",&t); 11 while(t--) 12 { 13 int i,n,m; 14 scanf("%d%d",&n,&m); 15 int cnt=0; 16 for(i=0;i<=m/5;i++) 17 { 18 int ln = n-i; 19 int lm = m-i*5; 20 if(lm>=ln&&lm<=2*ln) 21 { 22 cnt++; 23 } 24 } 25 printf("%d\n",cnt); 26 } 27 return 0; 28 }
【code3】:优化(推荐)
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 5 using namespace std; 6 7 int main() 8 { 9 int t; 10 scanf("%d",&t); 11 while(t--) 12 { 13 int n,m,mins,maks; 14 scanf("%d%d",&n,&m); 15 if(m>=n) maks=(m-n)/4; 16 else 17 { 18 puts("0"); 19 continue; 20 } 21 if(m-2*n>=0) 22 { 23 if((m-2*n)%3 == 0) 24 mins=(m-2*n)/3; 25 else 26 mins=(m-2*n)/3 + 1; 27 } 28 else mins=0; 29 printf("%d\n",maks-mins+1); 30 } 31 return 0; 32 }