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

来源:互联网 发布:des加密解密算法 f函数 编辑:程序博客网 时间:2024/06/02 10:11
很久以前写过一次,现在用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[N],q[N],f[N];
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;
}

0 0
原创粉丝点击