poj3133 插头dp

时间:2023-03-09 07:44:51
poj3133 插头dp
#include <iostream>
#include <cstdio>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
const int INF=;
int nrows,ncols;
int G[][];
struct State
{
int up[];
int left;
int encode()const
{
int key=left;
for(int i=; i<ncols; i++)
key=key*+up[i];
return key;
}
bool next(int row, int col, int U, int D, int L, int R, State &T)const
{
if( row==nrows- && D != ) return false; //最下行不能有向下的插头
if( col==ncols- && R != ) return false; //最右列右边不能有插头
int must_left=(col>&&left!=);// 是否必须要左插头
int must_up =(row>&&up[col]!=);//是否必须要右插头
if((must_left!= && L!=left ) || (must_left== && L!= )) return false;//左插头不匹配
if((must_up != && U!=up[col])||(must_up== && U!= ) ) return false;//上插头不匹配
if(must_left && must_up && left!=up[col]) return false; for(int i=; i<ncols; i++)T.up[i]=up[i];
T.up[col]=D;
T.left=R;
return true;
}
};
int memo[][][];
int rec(int row, int col, const State &S)
{
if(col==ncols){ col=; row++;};
if(row==nrows)return ;
int key=S.encode();
int &res = memo[row][col][key];
if(res>=)return res;
res=INF;
State T;
if(G[row][col]<=)
{
if(S.next(row,col,,,,,T))res=min(res,rec(row,col+,T));
if(G[row][col]== )
for(int t=; t<= ; t++)
{
if(S.next(row,col,t,t,,,T))res=min(res,rec(row,col+,T)+);
if(S.next(row,col,t,,t,,T))res=min(res,rec(row,col+,T)+);
if(S.next(row,col,t,,,t,T))res=min(res,rec(row,col+,T)+);
if(S.next(row,col,,t,t,,T))res=min(res,rec(row,col+,T)+);
if(S.next(row,col,,t,,t,T))res=min(res,rec(row,col+,T)+);
if(S.next(row,col,,,t,t,T))res=min(res,rec(row,col+,T)+);
} }
else {
int t=G[row][col]-;
if(S.next(row,col,t,,,,T))res=min(res,rec(row,col+,T)+);
if(S.next(row,col,,t,,,T))res=min(res,rec(row,col+,T)+);
if(S.next(row,col,,,t,,T))res=min(res,rec(row,col+,T)+);
if(S.next(row,col,,,,t,T))res=min(res,rec(row,col+,T)+);
}
return res;
}
int main()
{
while(scanf("%d%d",&nrows,&ncols)==&&nrows&&ncols)
{
for(int i=; i<nrows; i++)
for(int j=; j<ncols; j++)
scanf("%d",&G[i][j]);
State S;
memset(&S,,sizeof(S));
memset(memo,-,sizeof(memo));
int ans=rec(,,S);
if(ans==INF)ans=;
printf("%d\n",ans/);
}
return ;
}