BZOJ2425: [HAOI2010]计数
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2425
其实能够构成的数就是原数的排列(算前导0),然后组合计数一下就可以了。
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define maxn 50050 #define ll long long using namespace std; int cnt[20],n; ll ans,c[60][60]; char s[60]; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } ll cal(int x){ ll res=1; int now=x; rep(j,0,9) { res*=c[now][cnt[j]],now-=cnt[j]; } return res; } int main(){ c[0][0]=1; rep(i,1,50){ c[i][0]=1; rep(j,1,i) c[i][j]=c[i-1][j-1]+c[i-1][j]; } scanf("%s",s+1); n=strlen(s+1); rep(i,1,n) ++cnt[s[i]-'0']; rep(i,1,n) { rep(j,0,(s[i]-'0')-1) if (cnt[j]){ --cnt[j]; ans+=cal(n-i); ++cnt[j]; } --cnt[s[i]-'0']; } printf("%lld\n",ans); return 0; }