题意:

给你一个数n

问把这个数的各个数位重新排列,问

有多少种排列被d整除

题解:

状压dp

f[i][j]表示在i状态下%d=j

然后转移

最后不要忘记组合数

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2005;
int T,d,len,a[N],v[N],tot[N],f[N][N];
char ch[N];
int main()
{
    scanf("%d",&T);
    while (T--)
     {
         scanf("%s",ch);
        scanf("%d",&d);
        len=strlen(ch);
        for (int i=0;i<=9;i++)v[i]=1,tot[i]=0;
        for (int i=0;i<len;i++)
         {
            a[i]=ch[i]-'0';
            tot[a[i]]++;
            v[a[i]]*=tot[a[i]];
         }
        memset(f,0,sizeof f);    
        f[0][0]=1;
        for (int i=0;i<1<<len;i++)
         for (int k=0;k<d;k++)
          if (f[i][k])
           for (int x=0;x<len;x++)
            if(((1<<x)&i)==0)
             f[i|(1<<x)][(a[x]+k*10)%d]+=f[i][k];
        for (int i=0;i<=9;i++)f[(1<<len)-1][0]/=v[i];
        printf("%d\n",f[(1<<len)-1][0]);
     }
    return 0;
}

 

posted on 2018-02-17 10:10  宣毅鸣  阅读(124)  评论(0编辑  收藏  举报