BZOJ 2246 [SDOI2011]迷宫探险 (记忆化搜索)
题目大意:太长了,略
bzoj luogu
并没有想到三进制状压
题解:
3进制状压陷阱的状态,0表示这种陷阱的状态未知,1已知危险,2已知不危险
然后预处理出在当前状态下,每种陷阱有害的概率,设为$g[s][i]$
已知是危险的,有害概率为1
已知是不危险的,有害概率为0
未知的部分用概率表格里符合当前状态的部分,才是正确的(比如第4个样例输出了0.857就是没用这种方法去求概率)
定义$f[x][y][s][h]$表示当前在(x,y),陷阱的状态为s,当前血量是h
然后记忆化爆搜即可
...
此题解针对在luogu上交了,WA了第2个/第8个/第10个点,然后“换了个枚举顺序”就恰好A掉了这道题的情况
仔细观察发现上面那种做法貌似是有一些问题的
比如从上一层xxxx往下走↓,走到了yyyy这个状态,然后,yyyy还会往上跑从xxxx更新,得到了一个#$%@的“最优解”,这可能是yyyy往上跑的最优解,但也可能不是!
因为你状态xxxx可能还有某个方向没有遍历,但我们草率得把f[xxxx]这个“并不最优解”去更新f[yyyy]
那如果在另一次搜索中,由某个状态zzzz往上走↑,又跑到了yyyy,由于访问过了yyyy,所以返回了f[yyyy],然而这个f[yyyy]可能并不是最优解,导致答案出错!
为了避免这种错误,我们额外记录一维,表示从那个方向跑到当前状态,$f[x][y][s][h][t]$,t表示上一层是从哪个方向来的即可,虽然牺牲了一些常数但保证了答案的正确性!
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define N 35 5 #define M 250 6 #define dd double 7 #define idx(x) (x-'A'+1) 8 using namespace std; 9 10 int n,m,sx,sy,K,H; 11 char str[N][N]; 12 int xx[]={-1,0,1,0},yy[]={0,1,0,-1}; 13 int pw[]={1,3,9,27,81,243,729}; 14 int mp[N][N],pro[M]; 15 dd f[N][N][M][7][5],g[M][7],dan[7]; 16 bool vis[N][N][M][7][5]; 17 bool check(int x,int y){ 18 if(x<1||x>n||y<1||y>m||mp[x][y]==-1) return 0; 19 else return 1;} 20 int p[M][7]; 21 dd dfs(int x,int y,int s,int h,int fa) 22 { 23 if(h<=0) return 0; 24 if(vis[x][y][s][h][fa]) return f[x][y][s][h][fa]; 25 vis[x][y][s][h][fa]=1; 26 if(mp[x][y]==K+1){ 27 f[x][y][s][h][fa]=1; 28 return 1; 29 }int tx,ty,t1,t2,pt; 30 dd tmp=0; 31 for(int i=0;i<4;i++) 32 { 33 tx=x+xx[i],ty=y+yy[i]; 34 if(!check(tx,ty)) continue; 35 pt=mp[tx][ty],t1=t2=s; 36 dd ans1=0,ans2=0; 37 if(pt>0&&pt<=K&&!p[s][pt]) t1+=(1*pw[pt-1]); 38 if(pt>0&&pt<=K&&!p[s][pt]) t2+=(2*pw[pt-1]); 39 if(pt!=-1){ 40 if(g[s][pt]>0.0&&h>1) ans1=dfs(tx,ty,t1,h-1,(i+2)%4); 41 if(g[s][pt]<1.0)ans2=dfs(tx,ty,t2,h,(i+2)%4); 42 tmp=max(tmp,1.0*g[s][pt]*ans1+(1.0-g[s][pt])*ans2); 43 } 44 }f[x][y][s][h][fa]=tmp; 45 return f[x][y][s][h][fa]; 46 } 47 void Pre() 48 { 49 for(int i=0;i<(1<<K);i++) 50 scanf("%d",&pro[i]); 51 for(int i=0;i<pw[K];i++){ 52 int x=i,k=K; 53 while(k){ 54 p[i][k]=x/pw[k-1]; 55 x%=pw[k-1],k--;} 56 } 57 for(int i=0;i<pw[K];i++) 58 { 59 int tot=0,sum; 60 for(int j=0;j<K;j++) 61 dan[j+1]=0; 62 for(int s=0;s<(1<<K);s++){ 63 int fl=1; 64 for(int j=0;j<K;j++) 65 if((s&(1<<j))&&p[i][j+1]==2) {fl=0;break;} 66 else if((!(s&(1<<j)))&&p[i][j+1]==1) {fl=0;break;} 67 if(!fl) continue; 68 tot+=pro[s]; 69 }int x=i,k=K; 70 for(int k=1;k<=K;k++) 71 { 72 if(p[i][k]==0){ 73 sum=0; 74 for(int s=0;s<(1<<K);s++) 75 { 76 int fl=1; 77 for(int j=0;j<K;j++) 78 if((s&(1<<j))&&p[i][j+1]==2) {fl=0;break;} 79 else if((!(s&(1<<j)))&&p[i][j+1]==1) {fl=0;break;} 80 if(!fl) continue; 81 if(s&(1<<(k-1))) sum+=pro[s]; 82 }g[i][k]=1.0*sum/tot; 83 } 84 if(p[i][k]==1){g[i][k]=1.0;} 85 if(p[i][k]==2){g[i][k]=0.0;} 86 } 87 } 88 } 89 int main() 90 { 91 scanf("%d%d%d%d",&n,&m,&K,&H); 92 for(int i=1;i<=n;i++){ 93 scanf("%s",str[i]+1); 94 for(int j=1;j<=m;j++) 95 if(str[i][j]=='$') sx=i,sy=j; 96 else if(str[i][j]=='@') mp[i][j]=K+1; 97 else if(str[i][j]=='#') mp[i][j]=-1; 98 else if(str[i][j]=='.') mp[i][j]=0; 99 else mp[i][j]=idx(str[i][j]); 100 } 101 Pre(); 102 printf("%.3lf\n",dfs(sx,sy,0,H,4)); 103 return 0; 104 }
转载于:https://www.cnblogs.com/guapisolo/p/9958410.html
BZOJ 2246 [SDOI2011]迷宫探险 (记忆化搜索)相关推荐
- BZOJ 2246 [SDOI2011]迷宫探险 ——动态规划
概率DP 记忆化搜索即可,垃圾数据,就是过不掉最后一组 只好打表 #include <cstdio> #include <cstring> #include <iostr ...
- BZOJ.2246.[SDOI2011]迷宫探险(DP 记忆化搜索 概率)
题目链接 求最大的存活概率,DP+记忆化. 用f[s][x][y][hp]表示在s状态,(x,y)点,血量为hp时的存活概率. s是个三进制数,记录每个陷阱无害/有害/未知. 转移时比较容易,主要是在 ...
- 01迷宫(记忆化搜索)
01迷宫 题目描述: 有一个由01组成的n*n格迷宫,若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上.那么对于给定的迷宫,询问从 ...
- BZOJ 1079: [SCOI2008]着色方案 记忆化搜索
1079: [SCOI2008]着色方案 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- 洛谷P1141 01迷宫【记忆化搜索】
题目链接:P1141 01迷宫 程序说明: 可以用bfs来做,但是数据毒瘤,如果每次询问都运行一次bfs,会有三个TLE..可以将路途经过的点储存起来并且记录答案,如果询问的点已经被记录了答案,直接输 ...
- 蓝桥 迷宫寻宝 记忆化搜索
问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...
- bzoj2246: [SDOI2011]迷宫探险
2246: [SDOI2011]迷宫探险 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 202 Solved: 118 [Submit][Stat ...
- 【BZOJ2246】[SDOI2011]迷宫探险(搜索,动态规划)
[BZOJ2246][SDOI2011]迷宫探险(搜索,动态规划) 题面 BZOJ 洛谷 题解 乍一看似乎是可以求出每个东西是陷阱的概率,然而会发现前面走过的陷阱是不是陷阱实际上是会对当前状态产生影响 ...
- BZOJ 1589 Trick or Treat on the Farm (tarjan缩点,记忆化搜索)[Usaco 2008 Dec Gold]【BZOJ计划】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://hydro.ac/d/bzoj/p/1589 Problem 每年万圣 ...
最新文章
- Strategy_Requirement1
- 从0到1构建数据科学竞赛知识体系,有夕,鱼佬,茂霖等竞赛大咖将特邀分享...
- 谷歌自锤Attention:纯注意力并没那么有用,Transformer组件很重要
- ElementUI改变el-table的表头颜色以及各行的颜色
- 原型图和设计常犯错误,导致前端页面返工
- python算法应用(六)——搜索与排名2(PageRank算法及其拓展应用)
- jQuery dataTables四种数据来源[转]-原文地址:http://xqqing79.iteye.com/blog/1219425
- 第二阶段冲刺第八天(6月7号)
- exchange 日常管理之八:合并用户邮箱
- 18.nginx 服务器的代理服务
- ArcGIS操作小技巧(一)之属性表中显示出小数点前面的 0
- 课堂测试2014.3.10
- linux下测试权限,linux 文件权限
- PPC手机上网设置大全
- python源码中明明没有逻辑代码 为什么还能执行呢
- MTK修改sysemUI下拉的宽度为全屏
- 大童保险发生工商变更:安信信托彻底退出,德弘资本晋升为大股东
- OpenCV图片拼接
- 段间转移、长调用、短调用
- js 的Trim、LTrim、RTrim函数