您的位置:首页 > 其它

bzoj 1187 神奇的游乐园 | 插头dp

2015-11-16 10:39 281 查看
很久以前写过一次,现在用hash再写一遍。打重变量名了。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>

#define md
#define ll long long
#define inf (int) 1e9
#define eps 1e-8
#define N 5010
using namespace std;
int a[110][10];
struct ha
{
	int sz;
	int a
,q
,f
;
	void clear()
	{
		memset(a,-1,sizeof(a));
		sz=0;
	}
	void push(int x,int d)
	{
		int pos=x%N;
		while (a[pos]!=-1&&a[pos]!=x) { pos++; if (pos>=N) pos-=N; }
		if (a[pos]==-1)
		{
			q[++sz]=pos; a[pos]=x; f[pos]=d;
		}
		else f[pos]=max(f[pos],d);
	}
} hash[2];
int get(int s,int p,int l=2)
{
	return (s>>(p*l))&((1<<l)-1);
}
void ch(int &s,int p,int d,int l=2)
{
	s^=get(s,p)<<(p*l);
	s|=d<<(p*l);
}

int main()
{
	//freopen("data.in","r",stdin); freopen("data.out","w",stdout);
	int n,m;
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=m;j++)
	    scanf("%d",&a[i][j]);
	int now=0,pre=1,ans=-inf;
	hash[now].clear(); hash[pre].clear(); 
	hash[now].push(0,0);
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=m;j++)
		{
			swap(now,pre);
			hash[now].clear();
			for (int k=1;k<=hash[pre].sz;k++)
			{
				int pos=hash[pre].q[k];
				int s=hash[pre].a[pos],d=hash[pre].f[pos],S;
				int p=get(s,j-1),q=get(s,j);
				//printf("now: ij %d %d sd %d %d pq %d %d\n",i,j,s,d,p,q);
				if (p&&q)
				{
					if (p==1&&q==1)
					{
						S=s; ch(S,j-1,0); ch(S,j,0);
						int sum=0;
						for (int w=j+1;w<=m;w++)
						{
							int x=get(s,w);
							if (sum==0&&x==3) { ch(S,w,1); break;}
							if (x==1) sum++; else if (x==3) sum--;
						}
						hash[now].push(S,d+a[i][j]);
					}
					else if (p==3&&q==3)
					{
						S=s; ch(S,j-1,0); ch(S,j,0);
						int sum=0;
						for (int w=j-2;w>=0;w--)
						{
							int x=get(s,w);
							if (sum==0&&x==1) { ch(S,w,3); break; }
							if (x==1) sum++; else if (x==3) sum--;
						}
						hash[now].push(S,d+a[i][j]);
					}
					else if (p==3&&q==1)
					{
						S=s; ch(S,j-1,0); ch(S,j,0);
						hash[now].push(S,d+a[i][j]);
					}
					else if (p==1&&q==3)
					{
						S=s; ch(S,j-1,0); ch(S,j,0);
						if (S==0)
						{
							ans=max(ans,d+a[i][j]);
							hash[now].push(0,0);
						}
					}
				}
				else if (p==0&&q==0)
				{
					hash[now].push(s,d);
					S=s; ch(S,j-1,1); ch(S,j,3);
					hash[now].push(S,d+a[i][j]);
				}
				else if ((p==0)^(q==0))
				{
					hash[now].push(s,d+a[i][j]);
					S=s; ch(S,j-1,q); ch(S,j,p);
					hash[now].push(S,d+a[i][j]);
				}
			}
			//for (int k=1;k<=hash[now].sz;k++) printf("%d ",hash[now].a[hash[now].q[k]]); printf("\n");
		}
		int tot=0;
		for (int k=1;k<=hash[now].sz;k++)
		{
			int pos=hash[now].q[k];
			if (get(hash[now].a[pos],m)) hash[now].a[pos]=-1;
			else
			{
				hash[now].a[pos]<<=2;
				hash[now].q[++tot]=pos;
			}
		}
		hash[now].sz=tot;
	}
	printf("%d\n",ans);
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: