bzoj 1072

状压DP,f[i][j]表示在i状态下余数为j的情况

然后就是i的表示。。先认为数字互不相同(坑爹的想法= =),然后就有没有用到压缩状态

然后还要去重。。对每个数字来说除以数字个数的阶乘即可

 1 #include<bits/stdc++.h>
 2 #define inc(i,l,r) for(int i=l;i<=r;i++)
 3 #define dec(i,l,r) for(int i=l;i>=r;i--)
 4 #define link(x) for(edge *j=h[x];j;j=j->next)
 5 #define mem(a) memset(a,0,sizeof(a))
 6 #define inf 1e9
 7 #define ll long long
 8 #define succ(x) (1<<x)
 9 #define NM 15
10 using namespace std;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
14     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
15     return x*f;
16 }
17 char st[NM];
18 int a[NM],b[NM],d[succ(NM)][1005],s,T,t,n,m;
19 int main(){
20     freopen("data.in","r",stdin);
21     T=read();
22     while(T--){
23         mem(d);mem(a);mem(b);s=1;
24         scanf("%s",st+1);t=read();
25         n=strlen(st+1);
26         inc(i,1,n){
27             a[i]=st[i]-'0';
28             b[a[i]]++;
29         }
30         m=succ(n)-1;d[0][0]=1;
31         inc(i,0,m)
32         inc(j,0,t-1)if(d[i][j])
33         inc(k,1,n)
34         if((i&succ(k-1))==0)
35         d[i|succ(k-1)][(j*10+a[k])%t]+=d[i][j];
36         /*inc(i,0,m){
37             inc(j,0,t-1)printf("%d ",d[i][j]);printf("\n");
38         }*/
39         inc(i,0,9)
40         inc(j,1,b[i])s*=j;
41         printf("%d\n",d[m][0]/s);
42     }
43     return 0;
44 }
View Code

 

你可能感兴趣的:(bzoj 1072)