您的位置:首页 > 其它

FZU 1977 Pandora adventure 插头dp

2016-08-22 11:29 357 查看

题目链接

题意:

有些格子必须访问,有些格子不能访问,有些格子可以访问。

只能形成一个环。问线路的数量。

解:

之前做的一道题是要么可以访问,要么不能访问。区别是这个题

需要记录回路是否已经闭合。直接加在状态里即可。

而且必须要记录是否闭合!!!

1.这题时间卡的太紧,用stl模拟链地址法还是会超时。

2.行末shift()容易掉。

3.如果已经形成了闭合回路,当前格可能仍会有上插头或者左插头。这点非常重要。如果只能形成一个回路,而且必须在最后一个非障碍格子闭合,则不用考虑这些。

4.fzu用%lld 根本不行,要用%I64d,以后还是多用cin,cout



实际上只用判断是否有上插头即可,不可能已有线路闭合且有左插头。

代码:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
#define mes(a,x,s)  memset(a,x,(s)*sizeof a[0])
#define mem(a,x)  memset(a,x,sizeof a)
#define ysk(x)  (1<<(x))
typedef long long ll;
const int INF =0x3f3f3f3f;
const int maxn=12    ;
const int N=500000    ;
const int mod=19993   ;
int n,m,cur;
int a[maxn+3][maxn+3];

struct pll
{
ll first,second;
};
struct Hashmap
{
pll G
;
int nex
,fir[mod+5],nedge;

void insert(ll s,ll val)
{
int p=s%mod;
for(int i=fir[p];~i;i=nex[i])
{
if(G[i].first==s)
{
G[i].second+=val;
return;
}
}
G[nedge].first=s;
G[nedge].second=val;
nex[nedge]=fir[p];
fir[p]=nedge++;
}
void init()
{
nedge=0;
mem(fir,-1);
}

}hashmap[2];
struct Code
{
int bit[maxn+3],ended,ch[maxn+3],tot;
ll s;
void decode(ll x)
{
tot=0;
for0(i,m+1)
{
bit[i]=x&7;
tot=max(tot,bit[i]);
x>>=3;
}
ended=x&1;
tot++;
}
ll normalize()
{
mem(ch,-1);ch[0]=0;tot=1;
s=ended;
for(int i=m;i>=0;i--)
{
if(~ch[bit[i]])  bit[i]=ch[bit[i] ];
else
{
bit[i]=ch[bit[i]]=tot++;
}
s=(s<<3)|bit[i];
}
return s;
}
void shift()
{
for(int i=m;i>=1;i--)  bit[i]=bit[i-1];
bit[0]=0;
}
void color(int a,int b)
{
for0(i,m+1)  if(bit[i]==a) bit[i]=b;
}

}code;

void dpBlock(int x,int y,ll state,ll val)
{
if(y==m)  code.shift();
hashmap[cur].insert(code.normalize(),val);

}

void dpBlank(int x,int y,ll state,ll val)
{
const int p=code.bit[y-1],q=code.bit[y];
if(code.ended)
{
if(p||q||a[x][y]==2)  return;//****
if(y==m)  code.shift();
hashmap[cur].insert(code.normalize(),val);
return;
}
if(p&&q)
{
if(p==q)
{
code.bit[y-1]=code.bit[y]=0;
if(y==m) code.shift();
code.ended=1;
hashmap[cur].insert(code.normalize(),val);
}
else
{
code.color(p,q);
code.bit[y-1]=code.bit[y]=0;
if(y==m) code.shift();
hashmap[cur].insert(code.normalize(),val);
}
return;
}
if(p||q)
{
int t=p+q;
if(a[x][y+1])
{
code.bit[y-1]=0,code.bit[y]=t;
hashmap[cur].insert(code.normalize(),val);
}
if(a[x+1][y])
{
code.bit[y-1]=t,code.bit[y]=0;
if(y==m) code.shift();
hashmap[cur].insert(code.normalize(),val);
}
return;
}
if(!p&&!q)
{
if(a[x][y+1]&&a[x+1][y])
{
code.bit[y-1]=code.bit[y]=code.tot++;
hashmap[cur].insert(code.normalize(),val);
}
if(a[x][y]==1)
{
code.bit[y-1]=code.bit[y]=0;
if(y==m) code.shift();
hashmap[cur].insert(code.normalize(),val);
}
return;
}

}

void solve()
{
cur=0;
hashmap[cur].init();
hashmap[cur].insert(0,1);
for1(i,n) for1(j,m)
{
cur^=1;hashmap[cur].init();
for0(k,mod)  for(int l=hashmap[cur^1].fir[k];~l;l=hashmap[cur^1].nex[l])
{
pll now=hashmap[cur^1].G[l];
ll state=now.first;
ll val=now.second;
code.decode(state);
if(!a[i][j]) dpBlock(i,j,state,val);
else    dpBlank(i,j,state,val);
}
}
ll ans=0;
for0(k,mod)  for(int l=hashmap[cur].fir[k];~l;l=hashmap[cur].nex[l]) ans+=hashmap[cur].G[l].second;
cout<<ans<<endl;
}

int main()
{
int T,kase=0;cin>>T;
while(T--)
{
cin>>n>>m;
mem(a,0);char ch;
for1(i,n) for1(j,m)
{
cin>>ch;
if(ch=='X') a[i][j]=0;
else if(ch=='*')  a[i][j]=1;
else a[i][j]=2;
}
cout<<"Case "<<++kase<<": ";
solve();

}
return 0;
}
/*
12 12
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO
OOOOOOOOOOOO

1076226888605605706

12 12
************
************
************
************
************
************
************
************
************
************
************
************

12 12
O**********O
************
************
************
************
************
************
************
************
************
************
O**********O
771046925528298786

12 12
O**********O
************
*******O****
************
************
*****O******
************
************
*******O****
************
************
O**********O
6395622514350385989

4 4
XXXX
X*OX
XO*X
XXXX

3234
6 6
******
******
******
******
******
******
1222364

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp