【bzoj2331】[SCOI2011]地板 插头dp
来源:互联网 发布:淘宝商城入驻费用 编辑:程序博客网 时间:2024/04/29 02:54
插头dp
f[i][j][S]表示转移到第i行第j列轮廓线为S的方案数
0表示没有插头,1表示插头没有拐过弯,2表示插头拐过弯
1、
3进制不好写,写4进制
一共3^11个状态,200000左右
bit[i]=i*2
取出4进制的第i位 (S/(1<<bit[i-1]))%4
状态的第j位 1<<bit[j-1]
2、
bfs只记录有用的状态
3、
因为f[i][j]只与f[i][j-1]有关,所以不妨用滚动数组
4、
f[i][j][S]表示转移到第i行第j列轮廓线为S的方案数
0表示没有插头,1表示插头没有拐过弯,2表示插头拐过弯
1、
3进制不好写,写4进制
一共3^11个状态,200000左右
bit[i]=i*2
取出4进制的第i位 (S/(1<<bit[i-1]))%4
状态的第j位 1<<bit[j-1]
2、
bfs只记录有用的状态
3、
因为f[i][j]只与f[i][j-1]有关,所以不妨用滚动数组
4、
有下插头的位置正下方必然有上插头
#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<iostream>#define maxn 200010#define mod 20110520using namespace std;int a[110][110];int f[2][maxn],tot[2],hash[2][maxn],head[50010],to[maxn],next[maxn],bit[110];int n,m,now,pre,num;char s[110];void add(int s,int d){int x=s%50000;for (int p=head[x];p;p=next[p]) if (hash[now][to[p]]==s) { f[now][to[p]]=(f[now][to[p]]+d)%mod; return; }tot[now]++;hash[now][tot[now]]=s;f[now][tot[now]]=d;num++;to[num]=tot[now];next[num]=head[x];head[x]=num;}void dp(){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++){swap(now,pre);tot[now]=0;num=0;memset(f[now],0,sizeof(f[now]));memset(head,0,sizeof(head));for (int k=1;k<=tot[pre];k++){int s=hash[pre][k],num=f[pre][k];if (!num) continue;int p=(s/(1<<bit[j-1]))%4,q=(s/(1<<bit[j]))%4;if (!a[i][j]){if (!p && !q) add(s,num);}else if (!p && !q){if (a[i+1][j]) add(s+(1<<bit[j-1]),num);if (a[i][j+1]) add(s+(1<<bit[j]),num);if (a[i+1][j] && a[i][j+1]) add(s+(1<<bit[j-1]+1)+(1<<(bit[j]+1)),num);}else if (!p){if (q==1){s-=(1<<bit[j]);if (a[i][j+1]) add(s+(1<<bit[j]+1),num);if (a[i+1][j]) add(s+(1<<bit[j-1]),num);}else{s-=(1<<bit[j]+1);add(s,num);if (a[i+1][j]) add(s+(1<<bit[j-1]+1),num);}}else if (!q){if (p==1){s-=(1<<bit[j-1]);if (a[i][j+1]) add(s+(1<<bit[j]),num);if (a[i+1][j]) add(s+(1<<bit[j-1]+1),num);}else{s-=(1<<bit[j-1]+1);add(s,num);if (a[i][j+1]) add(s+(1<<bit[j]+1),num);}}else if (p==1 && q==1){s-=(1<<bit[j-1])+(1<<bit[j]);add(s,num);}}}}}int main(){for (int i=0;i<=100;i++) bit[i]=i*2;scanf("%d%d",&n,&m);if (n>=m){for (int i=1;i<=n;i++){scanf("%s",s+1);for (int j=1;j<=m;j++) if (s[j]=='_') a[i][j]=1; else a[i][j]=0;}}else{for (int i=1;i<=n;i++){scanf("%s",s+1);for (int j=1;j<=m;j++) if (s[j]=='_') a[j][i]=1; else a[j][i]=0;}swap(n,m);}dp();printf("%d\n",f[now][1]);return 0;}
0 0
- 【bzoj2331】[SCOI2011]地板 插头dp
- Bzoj2331[SCOI2011]地板:插头dp
- [插头DP] BZOJ2331 && SCOI2011 地板
- [bzoj2331][SCOI2011]地板
- BZOJ2331 [SCOI2011]地板
- BZOJ2331: [SCOI2011]地板
- 【SCOI2011】bzoj2331 地板
- bzoj2331: [SCOI2011]地板
- BZOJ 2331 SCOI2011 地板 插头DP
- [BZOJ]2331: [SCOI2011]地板 插头DP
- BZOJ 2331 SCOI 2011 地板 插头DP
- 【BZOJ 2331】 [SCOI2011]地板
- 2331: [SCOI2011]地板
- 2331: [SCOI2011]地板
- BZOJ 2331 [SCOI2011]地板
- ☆【动态规划】【SCOI2011】地板
- 插头DP
- 插头dp
- 人脸识别技术在公安领域的应用浅析【识别过程描述】
- 如何搭建一个git服务器?
- 装了双系统怎么删除一个
- NYOJ-96 n-1位数
- 快捷方式箭头
- 【bzoj2331】[SCOI2011]地板 插头dp
- iOS上架问题官方汇总
- 白话经典算法系列之四 直接选择排序及交换二个数据的正确实现
- C编译: makefile基础
- CoreData笔记
- 【LeetCode】LeetCode——第6题:ZigZag Conversion
- new Date()IE下不兼容问题
- 聚类算法总结
- 转换到 COFF 期间失败: 文件无效或损坏