bzoj 2331: [SCOI2011]地板 插头dp
2017-02-28 23:24
405 查看
用四进制表示状态。
用hash表把一个四进制数映射到一个小数上。
这样就可以memset了。
转移的时候分类讨论一下,特判下边界情况。
用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; }
相关文章推荐
- 【BZOJ】2331: [SCOI2011]地板 插头DP
- [SCOI2011][bzoj2331] 地板 [插头dp]
- BZOJ 2331 SCOI2011 地板 插头DP
- [插头DP] BZOJ2331 && SCOI2011 地板
- [插头DP] BZOJ 2331: [SCOI2011]地板
- BZOJ 2331 SCOI 2011 地板 插头DP
- 【bzoj2331】[SCOI2011]地板 插头dp
- Bzoj2331[SCOI2011]地板:插头dp
- 【BZOJ2331】[SCOI2011]地板 插头DP
- bzoj 2331: [SCOI2011]地板 插头DP
- BZOJ 2331 [SCOI2011]地板 ——插头DP
- [BZOJ]2331: [SCOI2011]地板 插头DP
- [bzoj2331][SCOI2011]地板
- bzoj:2331: [SCOI2011]地板
- bzoj2331 : [SCOI2011]地板 2011-12-20
- BZOJ 2331 地板(插头DP)
- BZOJ2331 [SCOI2011]地板
- BZOJ2331 [SCOI2011]地板
- BZOJ 2331 [SCOI2011]地板
- 【BZOJ 2331】 [SCOI2011]地板