首页 > 代码库 > HDU 1521
HDU 1521
指数型生成函数。做这题时,回去看看组合数学才知道,指数生成函数求的就是多重集合的r排列数。
#include <iostream>#include <cstdio>#include <algorithm>#define N 15using namespace std;struct PQ{ int p,q;};PQ c1[N],c2[N];int num[N];PQ cal;int Q[N];int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b);}PQ addsum(PQ a,PQ b){ PQ tmp; tmp.q=a.q*b.q; tmp.p=a.p*b.q+a.q*b.p; int g=gcd(max(tmp.p,tmp.q),min(tmp.p,tmp.q)); tmp.p/=g; tmp.q/=g; return tmp;}int main(){ int n,m,ptmp,qtmp; Q[0]=1; for(int i=1;i<N;i++) Q[i]=Q[i-1]*i; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++) scanf("%d",&num[i]); for(int i=0;i<N;i++){ c1[i].p=c2[i].p=0; c1[i].q=c2[i].q=1; } for(int i=0;i<=num[1];i++) c1[i].p=1,c1[i].q=Q[i]; for(int i=2;i<=n;i++){ for(int j=0;j<N;j++){ for(int k=0;k+j<N&&k<=num[i];k++){ ptmp=1,qtmp=Q[k]; cal.p=ptmp*c1[j].p;cal.q=qtmp*c1[j].q; ptmp=gcd(max(cal.p,cal.q),min(cal.p,cal.q)); cal.p/=ptmp; cal.q/=ptmp; c2[k+j]=addsum(cal,c2[k+j]); } } for(int j=0;j<N;j++) c1[j]=c2[j],c2[j].p=0,c2[j].q=1; } printf("%d\n",c1[m].p*Q[m]/c1[m].q); } return 0;}
HDU 1521
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。