zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        }
    }
    

      

  • 相关阅读:
    创建与合并分支
    Git丢弃本地修改
    《人月神话》小记
    财商培养
    赚钱有道,增加睡后收入
    学点经济学,升级认知
    保险小白普及知识
    管理决策、资源分配的最理想状态
    AI时代做一个终身学习者
    基于需求的测试
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6486903.html
Copyright © 2011-2022 走看看