Counting-ACM

解题思路:因为Gustavo只会1,2,3,4.但是她总是将4看成是1.所以她实际在做加法是只加了1,2,3三个数字。一个数n最多可以拆成全部由1组成的数,也就是说相加的数最多有n.这样设给出的数(也就是要相加得到的数字)为n, 一共有几个m个数字相加得到n.且m>=1且m<=n.设这m个数字当中有x个1,y个2,z个3.列出方程:x+2*y+3*z=n,x+y+z=m.因为x,y,z都大于等于0.得出z=(n-m-y)/2,x=(3*m-n-y),y<=n-m,y<=3*m-n.这样遍历y的所有可能性就可以得到x,z.至于4,可以将它看成1的特殊情况,也就是4可以代表1的所有情况。

这里所有求得情况的数目,我是用阶乘来做的。所以最后得到的结果就是C(m,z)*C(m,y)*(C(1,x)+C(2.x)...+C(x,x)+1).

// Counting.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> using namespace std; int Factorial(int a,int b){ int r1,i,j,r2; i=a; j=b; r1=1; r2=1; while(j>0){ r1=r1*i; --i; --j; } j=b; while(j>0){ r2=r2*j; --j; } return r1/r2; } int getNum(int n){ int addresult=0; for(int m=1;m<=n;++m){ int x,y,z; y=0; while((y<=(3*m-n))&&(y<=(n-m))){ if((n-m-y)%2==0&&(3*m-n-y)%2==0){ z=(n-m-y)/2; x=(3*m-n-y)/2; int d=1; if(y!=0)d=d*Factorial(m,y); if(z!=0)d=d*Factorial(m-y,z); if(x!=0){ int q=1; int p=x; while(p>0){ q=q+Factorial(x,p); --p; } d=d*q; } addresult=addresult+d; } ++y; } } return addresult; } int _tmain(int argc, _TCHAR* argv[]) { int n; while(cin>>n){ if(n==EOF)break; cout<<getNum(n)<<"/n"; } return 0; }  

你可能感兴趣的:(c)