http://poj.org/problem?id=1942
求C(n+m,n)
这题数据有点特殊....
C(a,b)的b 取min(b,a-b)就能ac了。。。
求组合只能实打实边乘边除了。。用ll或double足矣
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <iostream>
using namespace std;
__int64 inf=15;
double eps=0.000001;
__int64 C(__int64 a,__int64 b)
{
__int64 ans=1;
if (b<a-b) b=a-b;
__int64 i;
__int64 tmp=a-b;
for (i=a;i>b;i--)
{
ans*=i;
while(tmp>1&& ans%tmp==0 )
{ans/=tmp;tmp--;}
}
return ans;
}
int main()
{
__int64 n,m;
while(scanf("%I64d%I64d",&n,&m)!=EOF)
{
if (!n&&!m) break;
__int64 ans=1;
__int64 tmp=n+m;
ans=C(tmp,n);
printf("%I64d\n",ans);
}
return 0;
}
double:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <iostream>
using namespace std;
__int64 inf=15;
double eps=0.000001;
__int64 C(__int64 a,__int64 b)
{
double ans=1;
if (b<a-b) b=a-b;
__int64 i;
__int64 tmp=a-b;
for (i=a;i>b;i--)
{
ans*=i;
while(tmp>1&& (__int64)(ans)%tmp==0 )
{ ans=ans/ (double)tmp;
ans=(__int64)(ans+0.5);tmp--;}
}
return (__int64)(ans+0.5);
}
int main()
{
__int64 n,m;
while(scanf("%I64d%I64d",&n,&m)!=EOF)
{
if (!n&&!m) break;
__int64 ans=1;
__int64 tmp=n+m;
ans=C(tmp,n);
printf("%I64d\n",ans);
}
return 0;
}