第一次写状压DP,不知道怎么下手,所以只能看题解了(>_<~~~~)
代码如下:(只是多了几行注释)
#include<algorithm>//1023---1111111111,1024---1<<10
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int t,n,d,ans,f[1<<10][1<<10],digit[1<<10],tens[15],cnt[15],factorial[15];
char s[15];
int Get(int x){
int res=0;
while(x)
res+=x&1,x>>=1;
return res;
}
int main(){
factorial[0]=1,tens[0]=1;//factorial代表i的阶乘
for(int i=1;i<=10;i++)
factorial[i]=factorial[i-1]*i,tens[i]=tens[i-1]*10;
for(int i=0;i<1<<10;i++)
digit[i]=Get(i);//digit[i]=j代表十进制为i的数字转化成二进制有多少位1
scanf("%d",&t);
while(t--){
scanf("%s%d",s,&d);
memset(f,0,sizeof(f)),memset(cnt,0,sizeof(cnt));
f[0][0]=1,n=strlen(s);
for(int i=1;i<1<<n;i++){
for(int j=0;j<n;j++)
if(1<<j&i){
int temp=tens[digit[i]-1]%d*(s[j]-'0')%d;
for(int k=0;k<d;k++)
f[i][(k+temp)%d]+=f[1<<j^i][k];
}
}
ans=f[(1<<n)-1][0];//转化成二进制有n个1---这n个数全部选择,余数为0
for(int i=0;i<n;i++)
cnt[s[i]-'0']++;
for(int i=0;i<=9;i++)//一定要记得从0开始>o<
ans/=factorial[cnt[i]];//多重集的性质,(n1+n2+......+na)!/(n1!n2!......na!)
cout<<ans<<endl;
}
return 0;
}
by >o< neighthorn