[BZOJ2246][SDOI2011]迷宫探险(状压&概率DP)
来源:互联网 发布:幕墙易云计算手机 编辑:程序博客网 时间:2024/06/05 02:07
1、DP模型
用
2、边界&转移
边界为:
当
转移为(以下
当
当
当
3、关于g数组
上面
预处理
4、总结
结合「SCOI2008奖励关」「JLOI2013卡牌游戏」两题可以得出,像这样有限制条件,且在转移的过程中限制条件不断变化的概率DP,一般模型为:
5、代码
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;inline int read() { int res = 0; bool bo = 0; char c; while (((c = getchar()) < '0' || c > '9') && c != '-'); if (c == '-') bo = 1; else res = c - 48; while ((c = getchar()) >= '0' && c <= '9') res = (res << 3) + (res << 1) + (c - 48); return bo ? ~res + 1 : res;}inline char get() { char c; while (((c = getchar()) < 'A' || c > 'E') && c != '@' && c != '$' && c != '.' && c != '#'); return c;}const int N = 35, C = 267, R = 45, V = 10;int m, n, K, H, dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1}, pw[V], pb[R];char s[N][N]; double f[N][N][C][V], gw[C][V];bool vis[N][N][C][V];double chkmax(double &a, double b) {a = max(a, b);}int cyx(int S, int x) { return S / pw[x - 1] % 3;}int lpf(int S, int x, int y) { int res = S - cyx(S, x) * pw[x - 1]; return res + y * pw[x - 1];}void init() { int i, j, S; for (S = 0; S < pw[K]; S++) { int s1 = 0; for (i = 0; i < (1 << K); i++) { bool flag = 1; for (j = 1; j <= K; j++) { int xx = cyx(S, j); if (xx == 2) continue; if (xx != ((i >> j - 1) & 1)) {flag = 0; break;} } if (!flag) continue; s1 += pb[i]; for (j = 1; j <= K; j++) { if (cyx(S, j) != 2 || !((i >> j - 1) & 1)) continue; gw[S][j] += pb[i]; } } for (i = 1; i <= K; i++) gw[S][i] /= s1; }}double DP(int x, int y, int S, int h) { if (vis[x][y][S][h]) return f[x][y][S][h]; if (s[x][y] == '@') return vis[x][y][S][h] = 1, f[x][y][S][h] = 1; if (h == 0) return vis[x][y][S][h] = 1, f[x][y][S][h] = 0; vis[x][y][S][h] = 1; int i; for (i = 0; i < 4; i++) { int tx = x + dx[i], ty = y + dy[i], tt = s[tx][ty] - 'A' + 1; if (tx < 1 || tx > m || ty < 1 || ty > n || s[tx][ty] == '#') continue; if (s[tx][ty] == '.' || s[tx][ty] == '@' || s[tx][ty] == '$' || (tt >= 1 && tt <= K && cyx(S, tt) == 0)) chkmax(f[x][y][S][h], DP(tx, ty, S, h)); if (tt >= 1 && tt <= K && cyx(S, tt) == 1) chkmax(f[x][y][S][h], DP(tx, ty, S, h - 1)); if (tt >= 1 && tt <= K && cyx(S, tt) == 2) chkmax(f[x][y][S][h], DP(tx, ty, lpf(S, tt, 1), h - 1) * gw[S][tt] + DP(tx, ty, lpf(S, tt, 0), h) * (1.0 - gw[S][tt])); } return f[x][y][S][h];}int main() { int i, j, Sx, Sy; m = read(); n = read(); K = read(); H = read(); for (i = 1; i <= m; i++) for (j = 1; j <= n; j++) if ((s[i][j] = get()) == '$') Sx = i, Sy = j; pw[0] = 1; for (i = 0; i < (1 << K); i++) pb[i] = read(); for (i = 1; i <= K; i++) pw[i] = pw[i - 1] * 3; init(); printf("%.3lf\n", DP(Sx, Sy, pw[K] - 1, H)); return 0;}
阅读全文
0 0
- [BZOJ2246][SDOI2011]迷宫探险(状压&概率DP)
- 【BZOJ2246】[SDOI2011]迷宫探险【搜索】【概率DP】
- 【BZOJ2246】【codevs2135】迷宫探险,概率DP+记忆化搜索+状态压缩+运气
- 概率dp-九度-1546-迷宫问题
- 【SDOI2011】黑白棋(Nim游戏&&DP)
- [BZOJ2286][SDOI2011]消耗战(虚树+树形DP)
- 九度oj 题目1546:迷宫问题 (概率dp guess消元)
- zujt ZJUT 1423 地下迷宫 高斯消元法 概率DP
- HDU 4336 (概率DP+状压)
- [HDU 5816] Hearthstone (概率DP+状压)
- HDU 5816 Hearthstone(概率DP+状压)
- HDU 5816 Hearthstone (状压dp+概率)
- bzoj1076【概率dp+状压】
- poj3071(概率DP)
- codeforces148D(概率DP)
- poj2151(概率DP)
- hdu4870(概率dp)
- hdu3853(概率dp)
- 八种排序算法java实现(1)----冒泡排序
- 初始化窗体
- SQL Server 2005 开启数据库远程连接的方法
- java 循环 条件语句
- 写一个自己的springMVC?
- [BZOJ2246][SDOI2011]迷宫探险(状压&概率DP)
- 正则表达式
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- 大数据预科班作业13
- JSON入门Java篇-4-用HashMap来构建JSON
- springmvc+freemark+spring+mybatis+druid示例
- 关于使用kinect播放PPT
- [python]leetcode(49). Group Anagrams
- Java练习(3)