链接
https://www.luogu.org/problemnew/show/P1879
题目大意
给定一些玉米田,有些地方能种,种了玉米后,为了效应生物七年级上册内容合理密植,周围的地方不能种玉米,请求出种1..
颗玉米的方案数之和对
的取模结果
解题思路
状态压缩记忆化搜索
因为“记忆化搜索=动态规划”,所以“状态压缩记忆化搜索”=状压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);
}