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 */
相关文章推荐
- fzu1977之插头DP
- FZU 1977 Pandora adventure 解题报告(插头DP)
- FZU 1977 Pandora adventure (插头DP,常规)
- FZU 1977 Pandora adventure (插头dp)
- FZU - 1977 Pandora adventure【插头DP】
- FZU 1977 Pandora adventure (插头DP)
- foj 1977 Pandora adventure(插头DP)
- fzu 1977 Pandora adventure(插头DP一条回路 格子的占用或不占用)
- FOJ-1977 Pandora adventure 插头DP
- FZU 1977 Pandora adventure (DP)
- ★【插头DP | 搜索】【NOI2010】旅行路线
- HDU_P1693 Eat the Trees(插头DP)
- ural1519Formula 1 (插头DP)
- 【NOI2007/BZOJ1494】生成树计数 插头DP
- hdu 1693 Eat the Trees 插头dp
- 【BZOJ】2310: ParkII 插头DP
- [Poj2411]Mondriaan's Dream(状压dp)(插头dp)
- FZU---2030 括号问题[爆搜||DP]
- SCU2016-05 L题插头dp入门题
- URAL1519 Formula 1 【插头dp】