bzoj1072: [SCOI2007]排列perm

状压dp。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 12;

int f[1<<maxn][1010],cnt[maxn],fac[maxn];
char s[maxn];
int T,d,N,n;

int main() {
    fac[0]=1;
    for(int i=1;i<=10;i++) fac[i]=fac[i-1]*i;
    scanf("%d",&T);
    while(T--) {
        memset(cnt,0,sizeof(cnt));
        scanf("%s%d",s,&d);
        n=strlen(s);
        N=(1<<n)-1;
        for(int i=0;i<n;i++) cnt[s[i]-'0']++;
        
        memset(f,0,sizeof(f));
        f[0][0]=1;
        for(int i=0;i<N;i++)
        for(int j=0;j<d;j++) 
            if(f[i][j]) 
            for(int k=0;k<n;k++) if(!((1<<k)&i))
                f[i|(1<<k)][(j*10+(s[k]-'0'))%d]+=f[i][j];
        int res=f[N][0];
        for(int i=0;i<10;i++) res/=fac[cnt[i]];
        printf("%d\n",res);
    }
    return 0;
}
posted @ 2016-06-08 19:23  invoid  阅读(125)  评论(0编辑  收藏  举报