bzoj 1072(状压dp)

来源:互联网 发布:开发html的软件 编辑:程序博客网 时间:2024/06/06 00:16

传送门
定义dp[i][j]为状态i下余数为j的方案数。
然后正常dp即可,注意“264111”这种可能会算3!遍,所以最后要对dp[2^len-1][0]去重
dp过程出错以为是字符串没有输进去(第一个串为000,),调了半天鬼冒火,键盘是个什么东西好不好吃(╬▔皿▔)

#include<bits/stdc++.h>using namespace std;int MOD,dp[1026][1002],num[12],a[12],fac[12];char ss[15];int main() {//  freopen("bzoj 1072.in","r",stdin);    int kase;    scanf("%d",&kase);    fac[0]=1;    for (int i=1;i<=10;++i) fac[i]=i*fac[i-1];    while (kase--) {        memset(num,0,sizeof(num));        memset(dp,0,sizeof(dp));        scanf("%s%d",ss,&MOD);        int len=strlen(ss);         for (int i=0;i<len;++i)            ++num[a[i]=ss[i]-'0'];        dp[0][0]=1;        for (int i=0;i<(1<<len);++i)            for (int j=0;j<len;++j)                if ((i&(1<<j))==0)                    for (int m=0;m<MOD;++m)                        dp[i^(1<<j)][((m*10)+a[j])%MOD]+=dp[i][m];        int ans=dp[(1<<len)-1][0];        for (int i=0;i<10;++i)            ans/=fac[num[i]];        printf("%d\n",ans);    }    return 0;}
原创粉丝点击