• Corn Fields


    Corn Fields

    给出一个(m imes n)的矩形网格图,给出网格图中障碍物的位置,求向其中放若干个棋子互不相邻(当然也可以没有)的方案数(mod 10^8)(n,m imes 12)

    显然数据范围很小,考虑进制压缩,于是设(f[i][j])表示前i行,第i行状态为j的方案数,其中j有1的位置表示有棋子,可以先预处理出一行摆棋子合法的方案,记做(a[i][j])表示第i行第j个合法状态,因此有

    [f[i][j]=sum_{k=1}^{|a[i]|}f[i-1][k](!a[i][k]&a[i-1][k]) ]

    边界:(f[0][1]=a[0][1]=0)

    答案:(sum_{i=1}^{|a[m]|}f[m][i])

    参考代码:

    #include <iostream>
    #include <cstdio>
    #define il inline
    #define ri register
    #define cjx 100000000
    using namespace std;
    char c[13];
    int dp[13][4097],a[13][4097],
        at[13];
    il void get(char&);
    int main(){
        int n,m,li;scanf("%d%d",&n,&m);
        li=(1<<m)-1;
        for(int i(1),j,k;i<=n;++i){
            for(j=0;j<m;++j)get(c[j]);
            for(j=0;j<=li;++j){
                for(k=m-1;k>=0;--k)
                    if(j>>k&1){
                        if(c[k]=='0')break;
                        if(j>>(k+1)&1)break;
                    }
                if(k<0)a[i][++at[i]]=j;
            }
        }++at[0],dp[0][1]=1;
        for(int i(1),j,k;i<=n;++i)
            for(j=at[i];j;--j)
                for(k=at[i-1];k;--k){
                    if(a[i][j]&a[i-1][k])continue;
                    dp[i][j]+=dp[i-1][k];
                    if(dp[i][j]>cjx)dp[i][j]-=cjx;
                }int ans(0);
        for(int i(1);i<=at[n];++i)
            (ans+=dp[n][i])%=cjx;printf("%d",ans);
        return 0;
    }
    il void get(char &c){
        while(c=getchar(),c==' '||c=='
    '||c=='
    ');
    }
    
  • 相关阅读:
    re | [SWPU2019]ReverseMe
    wp | re | 2020“巅峰极客”网络安全技能挑战赛
    re | [CFI-CTF 2018]IntroToPE
    re | [FlareOn1]Bob Doge
    re | [ACTF新生赛2020]SoulLike
    re | [GKCTF2020]Chelly's identity
    ospf配置与ofps选举DR/BDR
    静态路由的配置
    配置三层交换机实现vlan间通信
    hybrid接口
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/11013928.html
Copyright © 2020-2023  润新知