http://www.elijahqi.win/2017/07/07/poj2663/
http://poj.org/problem?id=2663
题解大概在程序代码里了
#include<cstdio>
int state,h,w;
long long f[33][10];
void dfs1(int i,int p1,int p2,int x){//计算第i行p2状态准备放置x位置 前一行为p1的方案数
/*
if x>w 表示所有列都放完 第i行得到新的状态p2 f[i][p2]+=f[i-1][p1] 第二件事 返回
if p1的x位置==0;必须竖放 dfs1(i,p1,p2|1<<x-1,x+1);否则x位置==1{
x位置可以不放或者横放
不放:dfs1(i,p1,p2,x+1);
准备横放:if (x<w)不出界并且p1的x+1位置不为0 才可以横放
dfs(i,p1,p2+(修改x,x+1两个位置),x+2);
}
*/
if (x>3){
f[i][p2]+=f[i-1][p1];return ;
}
if ((p1&(1<<x-1))==0) dfs1(i,p1,p2+(1<<x-1),x+1);else{
dfs1(i,p1,p2,x+1);
if (x<3&&((p1&(1<<x))!=0)){
dfs1(i,p1,p2+(1<<x-1)+(1<<x),x+2);
}
}
}
int main(){
freopen("poj2663.in","r",stdin);
freopen("poj2663.out","w",stdout);
while (1){
scanf("%d",&h);
if (h==-1) break;
state=(1<<3)-1;
for (int j=0;j<=state;++j) f[0][j]=0;
f[0][state]=1;
for (int i=1;i<=h;++i){
for (int j=0;j<=state;++j) f[i][j]=0;
for (int j=0;j<=state;++j){
if (f[i-1][j]!=0){
dfs1(i,j,0,1);//四个参数i表示准备放置第i行 i-1行状态是j i行状态从0开始且从第一个位置开始
}else continue;
}
}
printf("%I64d\n",f[h][state]);
}
return 0;
}