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;
}

 

posted on 2015-12-01 21:31  ctlchild  阅读(343)  评论(0编辑  收藏  举报

导航