【状压DP】Day 12 提高组模拟C组 T3 玉米田 cowfood

链接

https://www.luogu.org/problemnew/show/P1879

题目大意

给定一些玉米田,有些地方能种,种了玉米后,为了效应生物七年级上册内容合理密植,周围的地方不能种玉米,请求出种1.. n 颗玉米的方案数之和对 1 e 8 的取模结果

解题思路

状态压缩记忆化搜索
因为“记忆化搜索=动态规划”,所以“状态压缩记忆化搜索”=状压DP


首先考虑搜索,枚举每个点,判断一下周围是否能填,统计方案数,预计得分60,实际得分90

因为搜索时冗杂的判断时的深搜枝节过多,我们可以用二进制取表示状态来减少判断的时间,预计得分100,实际得分100

代码

#include<cstdio>
#define re register
#define getchar() (S==T&&(T=(S=BB)+fread(BB,1,1<<15,stdin),S==T)?EOF:*S++)
#define mod 100000000
using namespace std;int f,n,m,ans,dp[13][1<<13];
char BB[1<<15],*S=BB,*T=BB;
char c;
bool a[13][13];
inline int read() 
{
    f=0;
    while(c=getchar(),c<=47||c>=59);f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),c>=48&&c<=57) f=(f<<3)+(f<<1)+c-48;
    return f;
}
inline void dfs(const int st,const int x,const int y,const int ct,const int e)
{
    if(ct==m+1)
    if(x==n)//直接把值都赋值给x
    {
        ans+=dp[x][y];
        ans%=mod;//记得要模
        return;
    }
    else
    {
        dp[x+1][st]+=dp[x][y];dp[x+1][st]%=mod;//状态转移
        return;
    }
    if(a[x][ct]&&!(y&(1<<(~-ct)))&&!e) dfs(st|1<<(~-ct),x,y,ct+1,1);//判断这里是否能种,能种则种
    dfs(st,x,y,ct+1,0);//考虑不种的情况
    return;
}
signed main()
{
    freopen("cowfood.in","r",stdin);
    freopen("cowfood.out","w",stdout);
    n=read();m=read();
    for(re int i=1;i<=n;i++)
     for(re int j=1;j<=m;j++) a[i][j]=read();
    dp[0][0]=1;
    for(re int i=0;i<=n;i++)
     for(re int j=0;j<(1<<m);j++) if(dp[i][j]) dfs(0,i,j,1,0);//枚举所有状态和所以行
    printf("%d",ans);
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/81087524