记录编号 186237 评测结果 AAAAAAAAAA
题目名称 [UVa 1214] 连线 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 11.742 s
提交时间 2015-09-12 09:40:41 内存使用 27.57 MiB
显示代码纯文本
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
const int INF=0x7fffffff/2;
int N,M;
int m[11][11];
class miku
{
    public:
	int x,y;
	int left;
	int up[13];
	void prpr()
	{
		memset(up,0,sizeof(up));
		x=y=1;left=0;
	}
	int mul()
	{
		int re=left;
		for(int i=1;i<=M;i++) re=re*3+up[i];
		return re;
	}
	bool changeornot(int L,int U,int R,int D)
	{
		if(U&&x==1) return 0;
		if(L&&y==1) return 0;
		if(R&&y==M) return 0;
		if(D&&x==N) return 0;
		if(L!=left) return 0;
		if(U!=up[y]) return 0;
		if(left>0&&up[y]>0&&left!=up[y]) return 0;
		up[y]=D;
		left=R;
		y++;
		return 1;
	}
};
int f[11][11][59050]={0};
int DP(miku &S)
{
	//1.三进制,0无插头,1是2产生的插头,2是3产生的插头
	//2.记忆化搜索+插头DP
	if(S.y>M)//该换行了
	{
		S.x++,S.y=1;
		S.left=0;//
	}
	if(S.x>N) return 0;
	int &ans=f[S.x][S.y][S.mul()];
	if(ans>=0) return ans;
	ans=INF;
	int x=S.x,y=S.y;
	miku T;
	int t;
	if(m[x][y]<=1)
	{//可以什么也不放
		T=S;if(T.changeornot(0,0,0,0)) ans=min(ans,DP(T));
	    if(m[x][y]==0)
	    {
		    for(t=1;t<=2;t++)
		    {
			T=S;if(T.changeornot(t,t,0,0)) ans=min(ans,DP(T)+2);
			T=S;if(T.changeornot(t,0,t,0)) ans=min(ans,DP(T)+2);
			T=S;if(T.changeornot(t,0,0,t)) ans=min(ans,DP(T)+2);
			T=S;if(T.changeornot(0,t,t,0)) ans=min(ans,DP(T)+2);
			T=S;if(T.changeornot(0,t,0,t)) ans=min(ans,DP(T)+2);
			T=S;if(T.changeornot(0,0,t,t)) ans=min(ans,DP(T)+2);
		    }
	    }
	}
	else
	{
		t=m[x][y]-1;
		T=S;if(T.changeornot(t,0,0,0)) ans=min(ans,DP(T)+1);
		T=S;if(T.changeornot(0,t,0,0)) ans=min(ans,DP(T)+1);
		T=S;if(T.changeornot(0,0,t,0)) ans=min(ans,DP(T)+1);
		T=S;if(T.changeornot(0,0,0,t)) ans=min(ans,DP(T)+1);
	}
	return ans;
}
bool read()
{
	scanf("%d%d",&N,&M);
	if(!N&&!M) return 0;
	for(int i=1;i<=N;i++)
		for(int j=1;j<=M;j++)
			scanf("%d",&m[i][j]);
	return 1;
}
void work()
{
	miku S;
	memset(f,-1,sizeof(f));
	S.prpr();
	int ans=DP(S);
	if(ans==INF) printf("0\n");
	else printf("%d\n",ans/2);
}
int main()
{
	freopen("manhattanwiring.in","r",stdin);
	freopen("manhattanwiring.out","w",stdout);
	while(read()) work();
	return 0;
}