lightoj 1021 - Painful Bases 状压DP

来源:互联网 发布:淘宝怎么搜爱奇艺会员 编辑:程序博客网 时间:2024/06/11 06:01

给定一个base进制和一个模数k,然后给个base进制下的数字,问这些数字全排列中(在base进制下)是k的倍数有几个。

范围又是16,又是状压DP。

对于一个状态i来言,如果i&(1<<j)不为0的话,第j数字就有可能是最低位,那么我们只需要考虑之前的余数再加上第j个数字来判断当前余数,k只有20,那么枚举k的状态是可行的。

#include<bits/stdc++.h>using namespace std;#define ll long longll dp[(1<<16)+3][22];int num[22];char s[22];int main(){    int t;    scanf("%d",&t);    for(int cas=1;cas<=t;cas++)    {        int b,k;        scanf("%d %d",&b,&k);        scanf("%s",s);        int len=strlen(s);        for(int i=0;i<len;i++)            num[i]=s[i]>='A'?(10+s[i]-'A'):s[i]-'0';        memset(dp,0,sizeof(dp));        dp[0][0]=1;        for(int i=0;i<(1<<len)-1;i++)        {            for(int j=0;j<k;j++)            {                if(!dp[i][j]) continue;                for(int x=0;x<len;x++)                {                    if((i&(1<<x))==0)                    {                        dp[i|(1<<x)][(j*b+num[x])%k]+=dp[i][j];                    }                }            }        }        printf("Case %d: %lld\n",cas,dp[(1<<len)-1][0]);    }    return 0;}



0 0
原创粉丝点击