【插头DP】 FZU 1977 Pandora adventure
通道:http://acm.fzu.edu.cn/problem.php?pid=1977
题意:单回路,有障碍点,必走点和非必走点。
思路:由于有格子可以不经过,那么就导致最后一个格子无法确定,我们找到输入中最后一个无障碍的格子,那么计算的时候,以后的格子作为最后一个即可。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int MAX_N = 13; 8 const int MAX_M = 13; 9 const int HASH = 10007; 10 const int MAX_S = 100007; 11 12 struct node { 13 int head[HASH], nxt[MAX_S]; 14 long long dp[MAX_S], st[MAX_S]; 15 int cnt; 16 void init() { 17 memset(head, -1, sizeof head); 18 cnt = 0; 19 } 20 void push(long long s, long long v) { 21 int now = s % HASH; 22 for(int i = head[now]; ~i; i = nxt[i]) if(st[i] == s) { 23 dp[i] += v; 24 return ; 25 } 26 st[cnt] = s; dp[cnt] = v; 27 nxt[cnt] = head[now]; 28 head[now] = cnt++; 29 } 30 }d[2]; 31 32 int n, m; 33 34 int find_pos(long long s, int p) { 35 return (s >> (p << 1)) & 3; 36 } 37 38 void tp(long long &s, int p, long long v) { 39 s &= (~(3ll << (p << 1))); 40 s |= (v << (p << 1)); 41 } 42 43 int find_r(long long s, int p) { 44 int cnt = 0; 45 for(int i = p; i <= m; ++i) { 46 if(find_pos(s, i) == 1) ++cnt; 47 else if(find_pos(s, i) == 2) --cnt; 48 if(!cnt) return i; 49 } 50 } 51 52 int find_l(long long s, int p) { 53 int cnt = 0; 54 for(int i = p; i >= 0; --i) { 55 if(find_pos(s, i) == 2) ++cnt; 56 else if(find_pos(s, i) == 1) --cnt; 57 if(!cnt) return i; 58 } 59 } 60 61 long long ans1; 62 int ex, ey; 63 int a[MAX_N][MAX_M]; 64 65 void blank(int i, int j, int cur) { 66 for(int k = 0; k < d[cur].cnt; ++k) { 67 long long t = d[cur].st[k]; 68 int l = find_pos(t, j - 1), r = find_pos(t, j); 69 if(l && r) { 70 if(l == 1 && r == 1) { 71 int tpos = find_r(t, j); 72 tp(t, j - 1, 0); tp(t, j, 0); tp(t, tpos, 1); 73 d[cur ^ 1].push(t, d[cur].dp[k]); 74 } else if(l == 2 && r == 1) { 75 tp(t, j - 1, 0); tp(t, j, 0); 76 d[cur ^ 1].push(t, d[cur].dp[k]); 77 } else if(l == 2 && r == 2) { 78 int tpos = find_l(t, j - 1); 79 tp(t, j - 1, 0); tp(t, j, 0); tp(t, tpos, 2); 80 d[cur ^ 1].push(t, d[cur].dp[k]); 81 } else { // 最后一个非障碍格子 82 tp(t, j - 1, 0); tp(t, j, 0); 83 if (!t) { 84 if (i > ex || i == ex && j >= ey) 85 ans1 += d[cur].dp[k]; 86 } 87 } 88 } else if(l) { 89 if(i < n) { 90 d[cur ^ 1].push(t, d[cur].dp[k]); 91 } 92 if(j < m) { 93 tp(t, j - 1, 0); tp(t, j, l); 94 d[cur ^ 1].push(t, d[cur].dp[k]); 95 } 96 } else if(r) { 97 if(j < m) { 98 d[cur ^ 1].push(t, d[cur].dp[k]); 99 } 100 if(i < n) { 101 tp(t, j - 1, r); tp(t, j, 0); 102 d[cur ^ 1].push(t, d[cur].dp[k]); 103 } 104 } else { // 新建 105 if (a[i][j] == 1) d[cur ^ 1].push(t, d[cur].dp[k]); 106 if(i < n && j < m) { 107 tp(t, j - 1, 1); tp(t, j, 2); 108 d[cur ^ 1].push(t, d[cur].dp[k]); 109 } 110 } 111 } 112 } 113 114 void block(int i, int j, int cur) { 115 for (int k = 0; k < d[cur].cnt; ++k) { 116 long long t = d[cur].st[k]; 117 int l = find_pos(t, j - 1), r = find_pos(t, j); 118 if (!l && !r) d[cur ^ 1].push(t, d[cur].dp[k]); 119 } 120 } 121 122 char str[20]; 123 124 int main() { 125 int T; 126 int cas = 0; 127 scanf("%d", &T); 128 while (T-- > 0) { 129 memset(a, 0, sizeof a); 130 scanf("%d%d", &n, &m); 131 for (int i = 1; i <= n; ++i) { 132 scanf("%s", str + 1); 133 for (int j = 1; j <= m; ++j) { 134 if (str[j] == '*') a[i][j] = 1; 135 else if (str[j] == 'O') a[i][j] = 2, ex = i, ey = j; 136 } 137 } 138 int cur = 0; 139 d[cur].init(); 140 d[cur].push(0, 1); 141 ans1 = 0; 142 for (int i = 1; i <= n; ++i) { 143 for (int j = 1; j <= m; ++j) { 144 d[cur ^ 1].init(); 145 if (a[i][j]) blank(i, j, cur); 146 else block(i, j, cur); 147 cur ^= 1; 148 } 149 for (int j = 0; j < d[cur].cnt; ++j) 150 d[cur].st[j] <<= 2; 151 } 152 printf("Case %d: %I64d\n", ++cas, ans1); 153 } 154 return 0; 155 } 156 157 /* 158 159 4 160 2 2 161 OO 162 OX 163 2 2 164 OO 165 O* 166 3 3 167 OOO 168 OO* 169 OOO 170 4 4 171 ***O 172 XO** 173 **O* 174 XX** 175 176 */
View Code
TAG:对于状态的计算,还是直接在L=1,R=2时计算吧,就不要往后面再转移了。
转载于:https://www.cnblogs.com/Rojo/p/4637073.html
【插头DP】 FZU 1977 Pandora adventure相关推荐
- 好学易懂 从零开始的插头DP(三)
好学易懂 从零开始的插头DP(三) 写在前面 这篇文章主要是介绍一些括号表示法和简单回路的基本变化,下一篇会是一些非回路(最小表示),毒瘤状态(正wa着所以咕着),结合矩阵乘法加速等一些复杂应用.下下 ...
- bzoj1814 Ural 1519 Formula 1(插头dp模板题)
1814: Ural 1519 Formula 1 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 924 Solved: 351 [Submit][S ...
- [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识--这真的是一种很锻炼人的题型-- 每一道题的状态都不一样 ...
- HDU4084 插头dp
题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,最后铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法 思路:插头DP或轮廓线,多加一维DP讨论就可以 注意插头DP状 ...
- POJ3133(插头dp)
传送门:http://poj.org/problem?id=3133 Manhattan Wiring Time Limit: 5000MS Memory Limit: 65536K ...
- P3272 [SCOI2011]地板(插头DP)
[题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] ( ...
- POJ 3133 Manhattan Wiring (插头DP)
Manhattan Wiring Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 1110 Accepted: 634 D ...
- URAL1519 Formula 1 —— 插头DP
题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB ...
- [集训队作业2018]小Z的礼物(min-max容斥,插头dp)
传送门 这种求 "取到所有物品的期望时间" 的题一般都用 min−maxmin-maxmin−max容斥 解决: 设t(i,j)t(i,j)t(i,j)为取到格子(i,j)(i,j ...
最新文章
- 语言模型如何为大象“称”体重?斯坦福提出“尺度探测”新思路
- 机器学习理论之SVM
- 用vue优雅地编写UI组件的几条指导原则
- Iterator 和 ListIterator 有什么区别?
- 突破Windows下select64的限制
- 深入理解this和call、bind、apply对this的影响及用法
- 云+X案例展 | 金融类:青云QingCloud助力泰康人寿云计算演进之路
- Hibernate一张图
- django 1.8 官方文档翻译: 2-5-10 数据库函数
- JS !(非运算)详解
- ACM常用算法及练习(2)
- 微信小程序demo、开发工具下载地址
- sublime好看的字体设置
- xp系统总是弹出宽带连接服务器,XP系统电脑总是弹出拨号连接怎么办-系统城...
- 站内信通知数据表设计
- 有孚网络与南方物流集团签署项目合作协议,共创数字服务领域新载体
- 靠查看英语资料 , “一不小心”成了国内第一
- 新基建下的工业互联网,等不到第四次工业革命
- w7电脑蓝屏怎么解决_详解win7电脑蓝屏怎么办
- actin/phobos后缀勒索病毒处理 百分百解密[cleverhorse@protonmail.