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

 

posted @ 2018-01-02 08:01  TRTTG  阅读(242)  评论(0编辑  收藏  举报