通道:http://acm.fzu.edu.cn/problem.php?pid=1977

题意:单回路,有障碍点,必走点和非必走点。

思路:由于有格子可以不经过,那么就导致最后一个格子无法确定,我们找到输入中最后一个无障碍的格子,那么计算的时候,以后的格子作为最后一个即可。

  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相关推荐

  1. 好学易懂 从零开始的插头DP(三)

    好学易懂 从零开始的插头DP(三) 写在前面 这篇文章主要是介绍一些括号表示法和简单回路的基本变化,下一篇会是一些非回路(最小表示),毒瘤状态(正wa着所以咕着),结合矩阵乘法加速等一些复杂应用.下下 ...

  2. 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 ...

  3. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识--这真的是一种很锻炼人的题型-- 每一道题的状态都不一样 ...

  4. HDU4084 插头dp

    题意:给定一个图,0是不能放的,然后现在有1X1和1X2方块,最后铺满该图,使得1X1使用次数在C到D之间,1X2次数随便,问有几种放法 思路:插头DP或轮廓线,多加一维DP讨论就可以 注意插头DP状 ...

  5. POJ3133(插头dp)

    传送门:http://poj.org/problem?id=3133 Manhattan Wiring Time Limit: 5000MS   Memory Limit: 65536K       ...

  6. P3272 [SCOI2011]地板(插头DP)

    [题面链接] https://www.luogu.org/problemnew/show/P3272 [题目描述] 有一个矩阵,有些点必须放,有些点不能放,用一些L型的图形放满,求方案数 [题解] ( ...

  7. POJ 3133 Manhattan Wiring (插头DP)

    Manhattan Wiring Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 1110   Accepted: 634 D ...

  8. URAL1519 Formula 1 —— 插头DP

    题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB ...

  9. [集训队作业2018]小Z的礼物(min-max容斥,插头dp)

    传送门 这种求 "取到所有物品的期望时间" 的题一般都用 min−maxmin-maxmin−max容斥 解决: 设t(i,j)t(i,j)t(i,j)为取到格子(i,j)(i,j ...

最新文章

  1. 语言模型如何为大象“称”体重?斯坦福提出“尺度探测”新思路
  2. 机器学习理论之SVM
  3. 用vue优雅地编写UI组件的几条指导原则
  4. Iterator 和 ListIterator 有什么区别?
  5. 突破Windows下select64的限制
  6. 深入理解this和call、bind、apply对this的影响及用法
  7. 云+X案例展 | 金融类:青云QingCloud助力泰康人寿云计算演进之路
  8. Hibernate一张图
  9. django 1.8 官方文档翻译: 2-5-10 数据库函数
  10. JS !(非运算)详解
  11. ACM常用算法及练习(2)
  12. 微信小程序demo、开发工具下载地址
  13. sublime好看的字体设置
  14. xp系统总是弹出宽带连接服务器,XP系统电脑总是弹出拨号连接怎么办-系统城...
  15. 站内信通知数据表设计
  16. 有孚网络与南方物流集团签署项目合作协议,共创数字服务领域新载体
  17. 靠查看英语资料 , “一不小心”成了国内第一
  18. 新基建下的工业互联网,等不到第四次工业革命
  19. w7电脑蓝屏怎么解决_详解win7电脑蓝屏怎么办
  20. actin/phobos后缀勒索病毒处理 百分百解密[cleverhorse@protonmail.

热门文章

  1. k8s kube-proxy ipvs
  2. Python分割视频
  3. JDK安装及环境变量配置
  4. 一个能修改排班表的html,大师排班表.html
  5. 计算机毕业设计Java中小学教师培训管理系统(源码+系统+mysql数据库+lw文档)
  6. vue 拼接html,vue.js中怎么拼接字符串?
  7. 13.4 掩膜的使用
  8. js 手机号、姓名、身份证号脱敏(打星号)
  9. centos7 磁盘空间不足扩容操作
  10. PCB里的铺铜和地(完整地平面)