BZOJ 1879 [Sdoi2009]Bill的挑战 ——状压DP

Posted SfailSth ——Salt Fish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1879 [Sdoi2009]Bill的挑战 ——状压DP相关的知识,希望对你有一定的参考价值。

本来打算好好写写SDOI的DP题目,但是忒难了,

太难了,就写的这三道题仿佛是可做的。

生在弱省真是兴奋。

这题目直接状压,f[i][j]表示匹配到i,状态集合为j的方案数,然后递推即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
 
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
 
const int md=1000003;
int dp[2][1<<16],T,n,m,len,g[60][30],ans=0;
char s[16][60];
 
void print(int x)
{
    F(i,0,n-1) printf("%d",(x>>i)&1);
}
 
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        ans=0;memset(g,0,sizeof g);
        scanf("%d%d",&n,&m);
        F(i,0,n-1) scanf("%s",s[i]+1);
        len=strlen(s[1]+1);
        F(i,1,len) F(j,0,25)
        {
            F(k,0,n-1)
            if (s[k][i]==\'?\'||(s[k][i]-\'a\')==j)
                g[i][j]|=(1<<k);
        }
        int now=1,pre=0;
        memset(dp[now],0,sizeof dp[now]);
        dp[now][(1<<n)-1]=1;
        F(i,1,len)
        {
            now^=1; pre^=1;
            memset(dp[now],0,sizeof dp[now]);
            F(j,0,(1<<n)-1)
                if (dp[pre][j])
                    F(k,0,25)
                        (dp[now][j&g[i][k]]+=dp[pre][j])%=md;
        }
        F(i,0,(1<<n)-1)
        {
            int t=i,cnt=0;
            while (t) {cnt+=(t&1);t>>=1;}
            if (cnt==m) (ans+=dp[now][i])%=md;
        }
        printf("%d\\n",ans);
    }
}

  

以上是关于BZOJ 1879 [Sdoi2009]Bill的挑战 ——状压DP的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1879SDOI2009Bill的挑战 [状压DP]

bzoj 1879 [Sdoi2009]Bill的挑战(状压DP)

BZOJ 1879 [Sdoi2009]Bill的挑战 ——状压DP

bzoj1879: [Sdoi2009]Bill的挑战 状压dp

bzoj 1879: [Sdoi2009]Bill的挑战状压dp

P2167 [SDOI2009]Bill的挑战