bzoj 1072: [SCOI2007]排列perm

2016-06-21

数字 难道是数位DP 可惜不是, 哎n<=10 我竟然没想到是状压DP,

f[i][j]表示i这个状态%d==j的方案数有多少,转移的时候枚举哪一个做最后一位。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstdlib>
 7 #include<map>
 8 #define ll long long
 9 #define M 2000009
10 using namespace std;
11 ll read()
12 {
13     char ch=getchar();
14     ll x=0,f=1;
15     for(;ch<'0'||ch>'9';ch=getchar())
16       if(ch=='-')
17         f=-1;
18     for(;ch>='0'&&ch<='9';ch=getchar())
19       x=x*10+ch-'0';
20     return x*f;
21 }
22 ll a[1024][1009],c[15],D[15];
23 int b[15],T;
24 int main()
25 {
26     c[0]=1;
27     for(int i=1;i<=10;i++)
28       c[i]=c[i-1]*i;
29     T=read();
30     for(;T;T--)
31       {
32           memset(D,0,sizeof(D));
33           char ch[15];
34           scanf("%s",ch);
35           int n=strlen(ch);
36         for(int i=0;i<n;i++)
37             {
38               b[i]=ch[i]-'0';
39             D[b[i]]++;
40           } 
41         int d=read();
42         int S=(1<<n);
43         memset(a,0,sizeof(a));
44         a[0][0]=1;
45         for(int i=1;i<S;i++)
46           for(int j=0;j<n;j++)
47               if(i&(1<<j))
48                 for(int k=0;k<d;k++)
49                    a[i][(k*10+b[j])%d]=a[i-(1<<j)][k]+a[i][(k*10+b[j])%d];
50         ll an=a[S-1][0];
51         for(int i=0;i<=9;i++)
52           an/=c[D[i]];
53         printf("%lld\n",an);
54       }
55     return 0;
56 }

 

posted @ 2016-06-21 17:08  xiw5  阅读(120)  评论(0编辑  收藏  举报