BZOJ2246 [SDOI2011]迷宫探险 【记忆化搜索dp + 概率】
题目




输入格式

输出格式
仅包含一个数字,表示在执行最优策略时,人物活着走出迷宫的概率。四舍五入保留3位小数。
输入样例
4 3 3 2
.$.
A#B
A#C
@@@
143 37 335 85 95 25 223 57
输出样例
0.858
提示


题解
毒瘤dp题
我们设\(f[x][y][s][h]\)表示从点\((x,y)\)出发,所有陷阱状态为\(s\),生命值为\(h\),存活的期望概率
我们枚举邻点,选择存活概率最大的作为当前\(f\)的值
除了墙,有以下情况:
①如果是空地或者终点,直接转移\(f[nx][ny][s][h]\)
②如果是陷阱:
1、如果陷阱已知
无害则同空地的转移
有害则转移的同时\(h - 1\)
2、如果陷阱位置
那么就是\(g[s][t] * f[nx][ny][s'][h - 1] + (1 - g[s][t]) * f[nx][ny][s''][h]\)
其中\(g[s][t]\)表示在已知状态为s的情况下,陷阱\(t\)有害的概率,可以预处理出来
\(s'\)和\(s''\)就是加入新状态的s
至于g数组的预处理,对于每种s,枚举未知位置的子集,将各种情况有害的加到对应陷阱去,然后除以总值
为什么换一个搜索顺序才能A???
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define REP(i,n) for (int i = 1; i <= (n); i++)
using namespace std;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
double f[32][32][250][6],g[250][6],p[100];
int vis[32][32][250][6],bin[10];
int n,m,K,H,Sx,Sy,X[4] = {1,0,-1,0},Y[4] = {0,-1,0,1};
int G[32][32];
void init(){
n = read(); m = read(); K = read(); H = read();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++){
char c = getchar();
while (!isprint(c)) c = getchar();
if (c == '.') G[i][j] = 0;
else if (c == '#') G[i][j] = -1;
else if (c == '$') G[i][j] = 0,Sx = i,Sy = j;
else if (c == '@') G[i][j] = -2;
else G[i][j] = c - 'A' + 1;
}
//REP(i,n) {REP(j,m) printf("%d ",G[i][j]); puts("");}
bin[0] = 1;
for (int i = 1; i <= K; i++) bin[i] = bin[i - 1] * 3;
//REP(i,K) printf("%d ",bin[i]); puts("");
int maxv = (1 << K) - 1,maxp = bin[K] - 1;
for (int s = 0; s <= maxv; s++) p[s] = read();
for (int s = 0; s <= maxp; s++){
int e = 0,t = 0; double sum = 0;
for (int i = s,j = 1; j <= K; j++,i /= 3){
if (i % 3 == 0) t |= (1 << j - 1);
else if (i % 3 == 2) e |= (1 << j - 1);
}
for (int i = t; ; i = (i - 1) & t){
int to = (e | i);
sum += p[to];
for (int j = 1; j <= K; j++)
if (to & (1 << j - 1)) g[s][j] += p[to];
if (!i) break;
}
for (int i = 1; i <= K; i++)
g[s][i] /= sum;
}
}
double F(int x,int y,int s,int h){
if (vis[x][y][s][h]) return f[x][y][s][h];
if (h == 0){
vis[x][y][s][h] = 1;
return f[x][y][s][h] = 0;
}
if (G[x][y] == -2){
vis[x][y][s][h] = 1;
return f[x][y][s][h] = 1;
}
vis[x][y][s][h] = 1;
double& ff = f[x][y][s][h];
ff = 0;
int nx,ny;
for (int k = 0; k < 4; k++){
nx = x + X[k];
ny = y + Y[k];
if (nx < 1 || ny < 1 || nx > n || ny > m || G[nx][ny] == -1) continue;
if (G[nx][ny] == 0 || G[nx][ny] == -2){
ff = max(ff,F(nx,ny,s,h));
}
else {
int t = G[nx][ny];
if ((s / bin[t - 1]) % 3 == 1) ff = max(ff,F(nx,ny,s,h));
else if ((s / bin[t - 1]) % 3 == 2) ff = max(ff,F(nx,ny,s,h - 1));
else {
ff = max(ff,g[s][t] * F(nx,ny,s + 2 * bin[t - 1],h - 1) + (1 - g[s][t]) * F(nx,ny,s + bin[t - 1],h));
}
}
}
return ff;
}
int main(){
init();
if (n == 0) return 0;
else printf("%.3lf\n",F(Sx,Sy,0,H));
return 0;
}
BZOJ2246 [SDOI2011]迷宫探险 【记忆化搜索dp + 概率】的更多相关文章
- BZOJ 2246 [SDOI2011]迷宫探险 (记忆化搜索)
题目大意:太长了,略 bzoj luogu 并没有想到三进制状压 题解: 3进制状压陷阱的状态,0表示这种陷阱的状态未知,1已知危险,2已知不危险 然后预处理出在当前状态下,每种陷阱有害的概率,设为$ ...
- 记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence
题目传送门 /* 记忆化搜索(DP+DFS):dp[i][j] 表示第i到第j个字符,最少要加多少个括号 dp[x][x] = 1 一定要加一个括号:dp[x][y] = 0, x > y; 当 ...
- HDU 1078 FatMouse and Cheese 记忆化搜索DP
直接爆搜肯定超时,除非你加了某种凡人不能想出来的剪枝...555 因为老鼠的路径上的点满足是递增的,所以满足一定的拓补关系,可以利用动态规划求解 但是复杂的拓补关系无法简单的用循环实现,所以直接采取记 ...
- 记忆化搜索 dp学习~2
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1331 Function Run Fun Time Limit: 2000/1000 MS (Java/ ...
- 【10.31校内测试】【组合数学】【记忆化搜索/DP】【多起点多终点二进制拆位Spfa】
Solution 注意取模!!! Code #include<bits/stdc++.h> #define mod 1000000007 #define LL long long usin ...
- hdu1331&&hdu1579记忆化搜索(DP+DFS)
这两题是一模一样的``` 题意:给了一系列递推关系,但是由于这些递推很复杂,所以递推起来要花费很长的时间,所以我要编程序在有限的时间内输出答案. w(a, b, c): 如果a,b,c中有一个值小于等 ...
- HDU - 6415 多校9 Rikka with Nash Equilibrium(纳什均衡+记忆化搜索/dp)
Rikka with Nash Equilibrium Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K ...
- hdu 4960 记忆化搜索 DP
Another OCD Patient Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Ot ...
- HNU OJ10086 挤挤更健康 记忆化搜索DP
挤挤更健康 Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 339, A ...
随机推荐
- SQL 转换函数
1.字符串与字符串相加 字符串相加 得到的是拼接成一列的字符串类型 例如 select name+code from car name是nvarchar code也是nvarchar ...
- mongodb复制集里查看主从操作日志oplog
MongoDB的replica set架构是通过一个日志来存储写操作的,这个日志就叫做 oplog .oplog.rs 是一个固定长度的 Capped Collection,它存在于local数据库中 ...
- Python 字符编码问题的处理
python中的字符编码问题往往是初学者容易弄不明白的问题, 要想将这个问题搞清楚,需要先弄明白以下的概念 decode 和 encode 函数的作用 字符串字面量的编码格式 decode(str) ...
- leetcode 127 单词接龙
给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度.转换需遵循如下规则: 每次转换只能改变一个字母. 转换过程中的中 ...
- Kruskal与Prim
一.最小生成树 在无向图中,连通且不含圈的图称为树(Tree).给定无向图G=(V,E),连接G中所有点,且边集是E的子集的树称为G的生成树(Spanning Tree),而权值最小的生成树称为最小生 ...
- 单源最短路SPFA
#include<iostream> #include<queue> #include<cstring> #define INF 0x3f3f3f3f using ...
- Koa -- 基于 Node.js 平台的下一代 web 开发框架 koa.bootcss.com
Koa -- 基于 Node.js 平台的下一代 web 开发框架 koa.bootcss.com
- 在 webpack 中使用 ECharts
http://echarts.baidu.com/tutorial.html#%E5%9C%A8%20webpack%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20ECharts W ...
- Noip2011提高组 聪明的质监员
题目传送门 讲真,既然质监员这么聪明,为什么要让我们帮他设计程序? 所以还是叫ZZ的质检员吧 其实,我最想说的,不是这个题,而是这个\(\Sigma\)(一见 \(\Sigma\) 就懵逼系列) 这个 ...
- pre-receive hook declined
没有master分支的代码提交权限. 分配权限或者提交分支合并申请