bzoj千题计划178:bzoj2425: [HAOI2010]计数
http://www.lydsy.com/JudgeOnline/problem.php?id=2425
题意转化:
给定一个集合S,求S的全排列<给定排列 的排列个数
从最高位开始逐位枚举确定
没有枚举到的位就是可重复集合的全排列
公式是 n!/ (n1!*n2!……)
高精?
用它的推导公式:C(n,n1)*C(n-n1,n2)*C(n-n1-n2,n3)……
#include<cstdio> #include<cstring> #include<iostream> using namespace std; typedef long long LL; char s[51]; int a[10],num[51]; LL ans; LL C[51][51]; LL getC(int n,int m) { if(C[n][m]) return C[n][m]; if(m==1) return n; if(n==m || !m) return 1; if(m>n) return 0; return C[n][m]=getC(n-1,m-1)+getC(n-1,m); } int main() { scanf("%s",s+1); int n=strlen(s+1); for(int i=1;i<=n;++i) { num[i]=s[i]-'0'; a[num[i]]++; } int m=n,tmp; LL res; for(int i=1;i<=n;++i) { m--; for(int j=0;j<num[i];++j) if(a[j]) { a[j]--; tmp=m; res=1; for(int k=0;k<=9;++k) if(a[k]) res*=getC(tmp,a[k]), tmp-=a[k]; ans+=res; a[j]++; } a[num[i]]--; } cout<<ans; }