LOJ #10171. 「一本通 5.4 例 2」牧场的安排

一、分析

数据范围:\(1\leq n,m\leq12\) ,考虑状压DP

将每一行的状态压为一个二进制数,设 \(f[i]\) 表示第 i 行的状态

二、按行转移

预处理出所有的合法状态(只处理相不相邻)

枚举出第 i-1 行及第 i 行的状态判断:

1、第 i 行的状态必须全在肥沃土地上( \(g[a]\)\(f[i]\) 的子集)

2、上下两行没有相邻的

#include<bits/stdc++.h>
using namespace std;
const int mod=1e8;
int n,m,x,cnt,f[15],g[1<<15],dp[15][1<<15];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>m>>n;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			cin>>x;
			f[i]=(f[i]<<1)+x;
		}
	}
	for(int i=0;i<(1<<n);i++){
		if(!(i&(i>>1))) g[++cnt]=i;//合法状态
	}
	dp[0][0]=1;
	for(int i=1;i<=m+1;i++){
		for(int a=1;a<=cnt;a++){
			for(int b=1;b<=cnt;b++){
				if((g[a]&f[i])==g[a]&&!(g[a]&g[b]))
					dp[i][g[a]]=(dp[i][g[a]]+dp[i-1][g[b]])%mod;
			}
		}
	}
    //dp[m+1][0]表示第m+1行不种任何草,相当于只在1~m行种植的所有方案
	cout<<dp[m+1][0]<<'\n';
	return 0;
}
posted @ 2026-06-14 21:33  Aguanenti  阅读(3)  评论(0)    收藏  举报