【题目来源】
http://poj.org/problem?id=3254
农夫约翰的土地由 M×N 个小方格组成,现在他要在土地里种植玉米。非常遗憾,部分土地是不育的,无法种植。而且,相邻的土地不能同时种植玉米,也就是说种植玉米的所有方格之间都不会有公共边缘。(注意:这里是上下左右边缘,不是两斜对角边缘)。现在给定土地的大小,请你求出共有多少种种植方法。土地上什么都不种也算一种方法。
【输入格式】
第 1 行包含两个整数 M 和 N。
第 2…M+1 行:每行包含 N 个整数 0 或 1,用来描述整个土地的状况,1 表示该块土地肥沃,0 表示该块土地不育。
【输出格式】
输出总种植方法对 100000000 取模后的值。
【算法分析】
以样例为例,我们可以一行一行的考虑。
假如对于每一行,用1表示放牛,0表示不放牛。
第一行的状态为:000、001、010、011(舍弃)、100、101、110(舍弃)、111(舍弃)
符合题意的状态只有5个,所以第一行有5种方案。
第二行的状态为:000、010
但是第二行中的010和第一行中的010冲突,所以如果第二行状态为010时,共有4种方案。状态为000时,有5种方案,所以一共有4+5=9种方案。
分析完我们会发现,对于每一行,都可以一个01串来表示这一行的状态,而这个状态可以用一个十进制整数来代替,也就是说,把这个状态压缩成了一个十进制整数,所以称为是状态压缩。棋盘模型是状态压缩最好的展示舞台之一。
本题中,dp[i][j] 就表示第i行状态为j时的方案数。
状态压缩dp中最常见的就是位运算,因为位运算可以很方便的判断当前状态是否合法。
以下情况不合法:
①土地本身不能耕种。(j&a[i])!=j
②同一行内有两棵玉米挨在一起。j&(j<<1)!=0
③相邻两行有玉米挨在一起。k&j!=0
-------------------------------------------------------------
无后效性:当前状态只受直接前驱状态影响
状态:用二进制表示状态。整数和状态是一一对应的,因为每个整数转化成二进制都是唯一的。
状态转移:是状态就可以转移。可以用整数的加减结果表示状态之间的转移。
状态压缩:其实就是将一个二进制转化成一个整数的意思。由于整数可以作为数组的下标,所以这样做会方便编码。
【程序代码】
#include <bits/stdc++.h>
using namespace std;
int a[15];
int dp[15][1<<13];
const int mod=1e8;
int m,n;
int main() {
while(cin>>m>>n) {
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
dp[0][0]=1;
int total=1<<n;
for(int i=1; i<=m; i++) {
for(int j=0; j<n; j++) {
int x;
cin>>x;
a[i]|=(x<<j);
}
}
for(int i=1; i<=m; i++) {
for(int j=0; j<total; j++) { //枚举所有状态
if((j&a[i])!=j) continue;//剔除掉与题目给的条件不符的
if(j&(j<<1)) continue;//剔除列相邻的
for(int k=0; k<total; k++) {
if(k&j) continue;//剔除行相邻的
dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
}
}
}
int ans=0;
for(int i=0; i<total; i++) {
ans=(ans+dp[m][i])%mod;
}
cout<<ans<<endl;
}
return 0;
}
/*
2 3
1 1 1
0 1 0
9
*/
【参考文献】
https://blog.csdn.net/qq_42936517/article/details/86547980?utm_medium=distribute.pc_relevant.none-task-blog-baidulandingword-3&spm=1001.2101.3001.4242
https://www.cnblogs.com/sweepy/p/13432840.html
https://blog.csdn.net/arliastark/article/details/80541787
https://blog.csdn.net/foreverlxm/article/details/22910461?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-5.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-5.channel_param
https://blog.csdn.net/y990041769/article/details/24658419?utm_source=blogkpcl3