【链接】
bzoj1072
【解题报告】
状压DP。。
定义
f[i][j]
表示状态为
i
,余数为
然后就很好解了。
这题有毒数据范围内爆搜也可以过。
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=12,maxm=1030,maxv=1005;
int T,n,m,S,cnt,a[maxn],f[maxm][maxv],num[maxn],w[maxn];
void Work()
{
memset(num,0,sizeof(num));
for (int i=0; i<=9; i++) w[i]=1;
char ch=getchar(); n=0;
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') a[++n]=ch-48,num[a[n]]++,w[a[n]]*=num[a[n]],ch=getchar();
cnt=1; for (int i=0; i<=9; i++) cnt*=num[i];
scanf("%d",&m); S=1<<n;
memset(f,0,sizeof(f));
f[0][0]=1;
for (int i=0; i<S; i++)
for (int j=1; j<=n; j++)
if (!(i&(1<<j-1)))
for (int k=0; k<m; k++)
f[i|(1<<j-1)][(k*10+a[j])%m]+=f[i][k];
for (int i=0; i<=9; i++) f[S-1][0]/=w[i];
printf("%d\n",f[S-1][0]);
}
int main()
{
freopen("1072.in","r",stdin);
freopen("1072.out","w",stdout);
scanf("%d",&T);
while (T--) Work();
return 0;
}