题目
dp[S|(1<<(j−1))][(k∗10+a[j])%d]+=dp[S][k].(还需要加上去重)
复杂度:O(T∗len∗mod∗2len)
这个去重好好体会。比如 s=“121” mod=4 ans=1; 第三位的1刚开始都没选 也就是dp[5]刚开始都没被更新 i=0是 j不能取3.
#include<bits/stdc++.h>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=10+1,M=1e3+5;
typedef long long ll;
char s[N];int a[N],vis[N],dp[1<<N][M];
int main(){
//freopen("input.txt","r",stdin);
int T,n,mod,t;scanf("%d",&T);
while(T--){
scanf("%s%d",s+1,&mod),n=strlen(s+1),t=(1<<n);
for(int i=1;i<=n;++i) a[i]=s[i]-'0';
m(dp,0),dp[0][0]=1;
for(int i=0;i<t;++i){
m(vis,0);
for(int j=1;j<=n;++j){
if(!(i&(1<<(j-1)))&&!vis[a[j]]){
vis[a[j]]=1;//去重
int d=(i|(1<<(j-1)));
for(int k=0;k<mod;++k){
dp[d][(k*10+a[j])%mod]+=dp[i][k];//因为多添了一位a[j] 就是k*10+a[j].
}
}
}
}
printf("%d\n",dp[t-1][0]);
}
}