【BZOJ2246】[SDOI2011]迷宫探险(搜索,动态规划)

题面

BZOJ

洛谷

题解

乍一看似乎是可以求出每个东西是陷阱的概率,然而会发现前面走过的陷阱是不是陷阱实际上是会对当前状态产生影响的。考虑一下状压,因为出了是陷阱和不是陷阱,还有一种情况是未知。所以三进制状压。

\(0\)表示是有害陷阱,\(1\)表示不是,\(2\)表示未知。

那么假如我们知道了一个当前的三进制状态,如何确定当前的某个未知的陷阱是否有害的概率呢?

这个显然可以暴力提前预处理出来。

那么这就很好办了,设\(f[x][y][hp][S]\)表示当前在\((x,y)\)位置,剩余血量为\(hp\),当前陷阱的状态集合为\(S\)的最大概率。那么直接记忆化爆搜就可以知道结果了。

然而我觉得这个做法是假的,因为你转移的时候可能成环,这也就解释了为什么不按照题解的方向就过不了,然而不这么做还能怎么做啊QwQ。

似乎BZOJ上的数据有锅,怎么交都是T,我蒯别的题解也T了。。。。

然后我改成scanf就WA了,应该数据锅了,到洛谷交吧。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define cmax(a,b) (a=((a)<(b)?(b):(a)))
int bin[]={1,3,9,27,81,243,729,2187,6561};
int let(int x,int k){return x/=bin[k];}
int rit(int x,int k){return x*=bin[k];}
int get(int x,int k){x/=bin[k];return x%3;}
double f[35][35][729][10];
bool vis[35][35][729][10];
int n,m,K,H,P[50];
char g[35][35];
double p[729][10];
int bx,by,ex,ey;
int d[4][2]={1,0,0,-1,-1,0,0,1};
double dfs(int x,int y,int S,int hp)
{
if(vis[x][y][S][hp])return f[x][y][S][hp];
if(!hp)return f[x][y][S][hp]=0;
if(g[x][y]=='@')return f[x][y][S][hp]=1;
vis[x][y][S][hp]=true;
for(int i=0;i<4;++i)
{
int xx=x+d[i][0],yy=y+d[i][1];
if(xx<1||yy<1||xx>n||yy>m)continue;
if(g[xx][yy]=='#')continue;
if(g[xx][yy]>='A'&&g[xx][yy]<='Z')
{
int k=g[xx][yy]-65;
if(get(S,k)<2)//Know
cmax(f[x][y][S][hp],dfs(xx,yy,S,hp-get(S,k)));
else//Unknow
cmax(f[x][y][S][hp],dfs(xx,yy,S-bin[k],hp-1)*p[S][k]+dfs(xx,yy,S-bin[k]*2,hp)*(1-p[S][k]));
}
else
cmax(f[x][y][S][hp],dfs(xx,yy,S,hp));
}
return f[x][y][S][hp];
}
int main()
{
scanf("%d%d%d%d",&n,&m,&K,&H);
for(int i=1;i<=n;++i)scanf("%s",g[i]+1);
for(int i=0;i<1<<K;++i)scanf("%d",&P[i]);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
if(g[i][j]=='$')bx=i,by=j;
else if(g[i][j]=='@')ex=i,ey=j;
if(!ex){puts("0.000");return 0;}
for(int S=0;S<bin[K];++S)
{
int sumP=0;
for(int i=0;i<1<<K;++i)
{
bool fl=true;
for(int j=0;j<K;++j)
{
int x=get(S,j);if(x==2)continue;
if(((i>>j)&1)!=x){fl=false;break;}
}
if(!fl)continue;
sumP+=P[i];
for(int j=0;j<K;++j)
if(get(S,j)==2&&(i&(1<<j)))p[S][j]+=P[i];
}
for(int j=0;j<K;++j)p[S][j]/=sumP;
}
printf("%.3lf\n",dfs(bx,by,bin[K]-1,H));
return 0;
}

【BZOJ2246】[SDOI2011]迷宫探险(搜索,动态规划)的更多相关文章

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

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

  2. P2489 [SDOI2011]迷宫探险 概率dp

    LINK:迷宫探险 题目中要求在最优的策略下的最大概率 而并非期望概率. 一个坑点 题目中虽然没有明说 但是 探险者是知道地图的模样和每个陷阱的概率的. 所以才有最优策略一说. 最优策略尽管不知道可以 ...

  3. BZOJ 2246 [SDOI2011]迷宫探险 ——动态规划

    概率DP 记忆化搜索即可,垃圾数据,就是过不掉最后一组 只好打表 #include <cstdio> #include <cstring> #include <iostr ...

  4. BZOJ 2246 [SDOI2011]迷宫探险 (记忆化搜索)

    题目大意:太长了,略 bzoj luogu 并没有想到三进制状压 题解: 3进制状压陷阱的状态,0表示这种陷阱的状态未知,1已知危险,2已知不危险 然后预处理出在当前状态下,每种陷阱有害的概率,设为$ ...

  5. BZOJ.2246.[SDOI2011]迷宫探险(DP 记忆化搜索 概率)

    题目链接 求最大的存活概率,DP+记忆化. 用f[s][x][y][hp]表示在s状态,(x,y)点,血量为hp时的存活概率. s是个三进制数,记录每个陷阱无害/有害/未知. 转移时比较容易,主要是在 ...

  6. [Bzoj2246]迷宫探险(概率+DP)

    Description 题目链接 Solution 用三进制表示陷阱状态,1表示有害,2表示无害,0表示不知道 用\(f[S][i]\)表示状态为S时陷阱i有害的概率,这个可以预处理出 \(d[S][ ...

  7. 2018年东北农业大学春季校赛 D wyh的迷宫【搜索】

    链接:https://www.nowcoder.com/acm/contest/93/D来源:牛客网 题目描述 给你一个n*m的迷宫,这个迷宫中有以下几个标识: s代表起点 t代表终点 x代表障碍物 ...

  8. 递归 dfs 记忆化搜索 动态规划

    今天做洛谷P1434 [SHOI2002]滑雪 的时候仔细想了想记忆化搜索 现在总结一下 为了描述问题的某一状态,必须用到该状态的上一状态,而描述上一状态,又必须用到上一状态的上一状态……这种用自已来 ...

  9. 洛谷P1605 迷宫 深度搜索 模板!

    题目背景 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫中移动有上下左右四种方式,每次只能移 ...

随机推荐

  1. LNMP V1.4一键快速部署Let's Encrypt免费SSL证书

    老左年前在"军哥LNMP V1.4测试版一键脚本安装以及功能上的升级体验"已经简单的体验到目前还没有正式版本的V1.4版本,理论上会在今年儿童节正式上线.从体验和实际的版本变动文档 ...

  2. 校内模拟赛 Zbq's Music Challenge

    Zbq's Music Challenge 题意: 一个长度为n的序列,每个位置可能是1或者0,1的概率是$p_i$.对于一个序列$S$,它的得分是 $$BasicScore=A\times \sum ...

  3. 线程池(ThreadPool)

    线程池概述 由系统维护的容纳线程的容器,由CLR控制的所有AppDomain共享.线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器. 线程池与线程 性能:每开启一个新 ...

  4. Kruskal算法-HDU1863畅通工程

    链接 [http://acm.hdu.edu.cn/showproblem.php?pid=1863] 题意 Problem Description 省政府"畅通工程"的目标是使全 ...

  5. 个人博客作业Week2 是否需要有代码规范

    问题:是否需要有代码规范 对于是否需要有代码规范,请考虑下列论点并反驳/支持: 1.这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 2.我是个艺术家,手艺人,我有 ...

  6. Android Studio中的Gradle是干什么的

    作者:ghui链接:https://www.zhihu.com/question/30432152/answer/48239946来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  7. Find Amir CodeForces - 805C (贪心+思维)

    A few years ago Sajjad left his school and register to another one due to security reasons. Now he w ...

  8. 基础-Math.floor与parseInt区别

    Math.floor只能对一个数向下取整,不能解析字符串 如: Math.floor(1.5) // 1 Math.floor(-2.1) // -3 Math.floor("3" ...

  9. PHP使用Redis实现消息队列

    消息队列可以使用MySQL来实现,可以参考博客PHP使用MySQL实现消息队列,虽然用MySQL可以实现,但是一般不这么用,因为MySQL的数据都存在硬盘中,而从硬盘中对MySQL的操作,I/O花费的 ...

  10. PAT 甲级 1045 Favorite Color Stripe

    https://pintia.cn/problem-sets/994805342720868352/problems/994805437411475456 Eva is trying to make ...