1.创建变量,状态转移数组dp,行内合法状态数组state,记录行内合法状态的某种属性的数组num,记录状态数量的count,原始行数组row,等
2.写判断合法的函数。判断行内合法ok(int sta),判断两行之间合法fit(int sta1,int sta2),等
3.写main函数:填充row(注意有时会把原图的01代码取反,以方便使用ok函数),填充state和num,初始化dp的起始值,开始利用fit函数进行状态转移,得出答案。
注意:1.根据题意,有时当前行能否到达某个状态取决于其上不止一行的状态。如果与前两行有关,则开三维数组,而不是只与前一行有关时开的二维数组。
2.状态数太多数组容易溢出,如果不好判断,可以把MN最大值输入后让程序输出count判断。
3.boolean类型函数注意感叹号= =
poj1185 ac代码
package algorithm;
import java.util.Scanner;
public class test{
public static int maxm=70;
public static
int dp[][][]=new int[110][maxm][maxm],
state[]=new int[maxm],
num[]=new int[maxm],
row[]=new int[110];
public static boolean ok(int sta){//行内合法
int k=sta;
if(((sta<<1)&k)==0&&((sta<<2)&k)==0){
return true;
}
return false;
}
public static boolean fit(int sta1,int sta2) {//两行之间合法
if((sta1&sta2)==0) {
return true;
}
return false;
}
public static void main(String args[]) {
Scanner sc=new Scanner(System.in);
int N,M;
N=sc.nextInt();
M=sc.nextInt();
char[] tmp;
for(int i=0;i<N;i++) {
tmp=sc.next().toCharArray();
for(int j=0;j<M;j++){
if(tmp[j]=='H') {
row[i]+=(1<<(M-j-1));
}
}
}
int count=0;
int t=0;
for(int i=0;i<1<<M;i++) {
if(ok(i)) {
state[count]=i;
t=i;
int sum=0;
while(t>0) {
if((t&1)==1) {
sum++;
}
t>>=1;
}
num[count++]=sum;
}
}
System.out.println(count);
//System.out.println("?");
for(int i=0;i<count;i++) {
if(!fit(row[0],state[i]))continue;
dp[0][i][0]=num[i];
}
for(int i=0; i<count; i++) //接着初始化dp[1][i][j],即第2行的情况
{
if(!fit(state[i],row[1])) continue;
for(int j=0; j<count; j++) //枚举第1行的状态
{
if(!fit(state[j],row[0])) continue;
if(!fit(state[i],state[j])) continue;
dp[1][i][j]=Math.max(dp[1][i][j] , dp[0][j][0]+num[i]);
//状态转移方程
//System.out.println(dp[1][i][j]);
}
}
for(int i=2;i<N;i++) {
for(int k=0;k<count;k++) {
if(!fit(row[i],state[k]))continue;
for(int kk=0;kk<count;kk++) {
if(!fit(row[i-1],state[kk]))continue;
for(int kkk=0;kkk<count;kkk++) {
if(!fit(row[i-2],state[kkk]))continue;
if(fit(state[k],state[kk])&&fit(state[k],state[kkk])&&fit(state[kk],state[kkk])) {
dp[i][k][kk]=Math.max(dp[i][k][kk], dp[i-1][kk][kkk]+num[k]);
}
}
}
}
}
int ans=0;
for(int i=0;i<count;i++) {
for(int j=0;j<count;j++) {
ans=Math.max(ans, dp[N-1][i][j]);
}
}
System.out.println(ans);
}
}