【Luogu】P2489迷宫探险(概率DP)
2024-10-21 15:43:22
设f[i][j][k][l]是当前在(i,j),对陷阱的了解状态为k(0表示了解该陷阱为无危险,1表示了解该陷阱有危险,2不了解),l表示当前血,走出迷宫的概率
dfsDP即可。 注意随时更新和细节。
#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 200
using namespace std;
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} int u[]={,,,-,};
int w[]={,,-,,}; char mp[maxn][maxn]; double p[maxn];
double g[maxn*][maxn];
int pw[maxn]; int n,m,e,h; int getlens(int x,int len){ return x/pw[len-]%; } double f[][][maxn*][];
bool vis[][][maxn*][]; int chan(int x,int len,int nu){
return x-getlens(x,len)*pw[len-]+nu*pw[len-];
} void dfs(int x,int y,int state,int blo){
//printf("%d %d\n",x,y);
//printf("%d %d %d %d %.3lf\n",x,y,state,blo,f[x][y][state][blo]);
if(vis[x][y][state][blo]) return;
if(mp[x][y]=='@'){ f[x][y][state][blo]=; vis[x][y][state][blo]=; return; }
if(blo==){ f[x][y][state][blo]=; vis[x][y][state][blo]=; return; }
vis[x][y][state][blo]=;
double &ans=f[x][y][state][blo];
for(int i=;i<;++i){
int nx=x+u[i],ny=y+w[i];
if(nx<||nx>n||ny<||ny>m||mp[nx][ny]=='#') continue;
char c=mp[nx][ny];
int now=c-'A'+;
if(c=='.'||c=='$'||c=='@'||(now>=&&now<=e&&getlens(state,now)==)){
dfs(nx,ny,state,blo);
ans=max(ans,f[nx][ny][state][blo]);
}
//if(now<1||now>e) continue;
if(now>=&&now<=e&&getlens(state,now)==){
dfs(nx,ny,state,blo-);
ans=max(ans,f[nx][ny][state][blo-]);
}
if(now>=&&now<=e&&getlens(state,now)==){
int sta=chan(state,now,);
int stb=chan(state,now,);
dfs(nx,ny,sta,blo-);
dfs(nx,ny,stb,blo); ans=max(ans,g[state][now]*f[nx][ny][sta][blo-]+(1.0-g[state][now])*f[nx][ny][stb][blo]);
}
}
f[x][y][state][blo]=ans;
return;
} int main(){
int sx,sy;
n=read(),m=read(),e=read(),h=read();
for(int i=;i<=n;++i){
scanf("%s",mp[i]+);
for(int j=;j<=m;++j)
if(mp[i][j]=='$'){
sx=i; sy=j;
}
}
for(int i=;i<(<<e);++i) p[i]=read();
int Max=;pw[]=;
for(int i=;i<=e;++i) pw[i]=pw[i-]*;
//printf("%d",Max);
for(int i=;i<=pw[e];++i){
int sum=;
for(int j=;j<(<<e);++j){
bool flag=;
for(int k=;k<=e;++k){
int now=getlens(i,k),ret=(j>>k-)&;
if(now==) continue;
if(now!=ret){
flag=;
break;
}
}
if(flag) continue;
sum+=p[j];
for(int k=;k<=e;++k){
if(getlens(i,k)!=||((j>>k-)&)==) continue;
g[i][k]+=p[j];
}
}
for(int j=;j<=e;++j) g[i][j]/=sum;
} dfs(sx,sy,pw[e]-,h);
printf("%.3lf",f[sx][sy][pw[e]-][h]);
return ;
}
最新文章
- C#编程语言与面向对象——抽象基类与接口
- css position, display, float 内联元素、块级元素
- phpQuery—基于jQuery的PHP实现
- POJ 2528 区间染色,求染色数目,离散化
- leetcode 9
- homework 08_2 C++11新特性作业之二
- java版 正文抽取 基于文字连接比
- Vue购物车实例
- Linux下用户和组管理
- 项目中BigDecimal与Double使用场景
- (Python)PO设计模式
- 077、跨主机使用Rex-Ray volume (2019-04-24 周三)
- server 打开失败
- Android清单文件合并的那些事
- JDK8 stream toMap() java.lang.IllegalStateException: Duplicate key异常解决(key重复)
- Java SE之向上转型与向下转型
- GDC2017 把“现实的天空”在游戏内再现【Forza Horizon 3】的天空表现
- Js分支结构 switch--case
- Java开发工程师学习路线
- SQL语句的执行顺序 1>;优先执行,然后依数字排序