题目链接:BZOJ 1072
dp[i][j]:i表示每个数选与不选的状态,j表示当前状态的余数
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int a[20],num[20],p[20],dp[1025][1005];
int main(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
int T,N; scanf("%d",&T);
char s[20];
while(T--){
memset(dp,0,sizeof(dp));
scanf("%s",s+1); scanf("%d",&N);
int L=strlen(s+1);
for(int i=0;i<=9;i++)p[i]=1, num[i]=0;
for(int i=1;i<=L;i++){
a[i]=s[i]-'0'; num[a[i]]++;
p[a[i]]*=num[a[i]];
}
dp[0][0]=1;
for(int i=0;i<(1<<L);i++){
for(int j=0;j<N;j++){
for(int k=0;k<L;k++){
if(!(i&(1<<k))){
dp[i|(1<<k)][(a[k+1]+j*10)%N]+=dp[i][j];
}
}
}
}
for(int i=0;i<=9;i++){
dp[(1<<L)-1][0]/=p[i];
}
printf("%d\n",dp[(1<<L)-1][0]);
}
return 0;
}