您的位置:首页 > 其它

bzoj 2331: [SCOI2011]地板 插头dp

2017-02-28 23:24 405 查看
  用四进制表示状态。

  用hash表把一个四进制数映射到一个小数上。

  这样就可以memset了。

  转移的时候分类讨论一下,特判下边界情况。

  

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define bq 1<<bit[j]
#define bp 1<<bit[j-1]
using namespace std;
int n,m;
int map[105][105],bi[105][105];
char s[105];
const int maxn=200010;
int f[2][maxn],tot[2],hash[2][maxn],head[maxn],ver[maxn],nxt[maxn],bit[110];
int num,pre,now;
const int mod = 20110520;
void add(int s,int d)
{
int x=s%50000;
for(int i=head[x];i;i=nxt[i])
{
if(hash[now][ver[i]]==s)
{
f[now][ver[i]]=(f[now][ver[i]]+d)%mod;
return ;
}
}
tot[now]++;
hash[now][tot[now]]=s;
f[now][tot[now]]=d;
num++;ver[num]=tot[now];nxt[num]=head[x];head[x]=num;
return ;
}
int main()
{
for(int i=1;i<=100;i++)bit[i]=i*2;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
for(int j=1;j<=m;j++)
{
if(s[j-1]=='*')map[i][j]=0;
else map[i][j]=1;
}
}
if(n<m)
{
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)bi[j][i]=map[i][j];
memset(map,0,sizeof(map));
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)map[j][i]=bi[j][i];
swap(n,m);
}
now=1;pre=0;tot[now]=1;hash[now][1]=0;f[now][1]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=tot[now];j++)hash[now][j]<<=2;
for(int j=1;j<=m;j++)
{
now^=1;pre^=1;
memset(head,0,sizeof(head));
memset(f[now],0,sizeof(f[now]));
tot[now]=0;num=0;
for(int k=1;k<=tot[pre];k++)
{
int s=hash[pre][k],num=f[pre][k];
if(!num)continue;
int p=(s/(bp))&3,q=(s/(bq))&3;
if(!map[i][j])
{
if(!p&&!q)add(s,num);
}
else if(!p&&!q)
{
add(s+(bp),num);
if(j<m)add(s|(bq),num),add(s|(bp+1)|(bq+1),num);
}
else if(!p)
{
if(q==1)
{
s^=(bq);
add(s|(bp),num);
if(j<m)add(s|(bq+1),num);
}
else
{
s^=(bq+1);
add(s|(bp+1),num);
add(s,num);
}
}
else if(!q)
{
if(p==1)
{
s^=(bp);
add(s|(bp+1),num);
if(j<m)add(s|(bq),num);
}
else
{
s^=(bp+1);
if(j<m)add(s|(bq+1),num);
add(s,num);
}
}
else if(p==1&&q==1)
{
add(s^(bq)^(bp),num);
}
}
}
}
int ans=0;
for(int i=head[0];i;i=nxt[i])
{
if(hash[now][ver[i]]==0)ans=f[now][ver[i]];
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: