概率DP
记忆化搜索即可,垃圾数据,就是过不掉最后一组
只好打表
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) int a[31][31],n,m,k,h,vis[250][31][31][6],b[10],id[50][50],cnt,stx,sty; int p[750],sum,p3[10]; double nsum,nhav; int naim,mov[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; double g[250][10]; double dp[250][31][31][6]; char s[40]; void recode3(int now) { F(i,1,k) b[i]=(now%p3[i])/p3[i-1]; } int encode2() { int ret=0; F(i,1,k) ret+=b[i]<<(i-1); return ret; } int encode3() { int ret=0; F(i,1,k) ret+=b[i]*p3[i-1]; return ret; } void dfs(int pos) { if (pos>k) { int x=encode2(); if (b[naim]==1) nhav+=p[x],nsum+=p[x]; else nsum+=p[x]; return; } if (b[pos]==2) { b[pos]=1; dfs(pos+1); b[pos]=0; dfs(pos+1); b[pos]=2; return; } else dfs(pos+1); return ; } double get(int now,int aim) { recode3(now); if (b[aim]==1) return 1.0; if (b[aim]==0) return 0.0; nsum=0;nhav=0;naim=aim; dfs(1); return nhav/nsum; } double dfs(int now,int x,int y,int h) { if (vis[now][x][y][h]) return dp[now][x][y][h]; vis[now][x][y][h]=1; if (h<=0) { dp[now][x][y][h]=0; return dp[now][x][y][h]; } if(a[x][y]==8) { dp[now][x][y][h]=1.0; return dp[now][x][y][h]; } F(i,0,3) { int tx=x+mov[i][0],ty=y+mov[i][1],aim,tohv,tont; if (tx<1||tx>n||ty<1||ty>m) continue; if (a[tx][ty]==7) continue; else if (a[tx][ty]==0||a[tx][ty]==8) dp[now][x][y][h]=max(dp[now][x][y][h],dfs(now,tx,ty,h)); else if (a[tx][ty]>=1&&a[tx][ty]<=5) { recode3(now); aim=a[tx][ty]; if (b[aim]==0) dp[now][x][y][h]=max(dp[now][x][y][h],dfs(now,tx,ty,h)); else if (b[aim]==1) dp[now][x][y][h]=max(dp[now][x][y][h],dfs(now,tx,ty,h-1)); else if (b[aim]==2) { b[aim]=0; tont=encode3(); b[aim]=1; tohv=encode3(); b[aim]=2; dp[now][x][y][h]=max(dp[now][x][y][h],g[now][aim]*dfs(tohv,tx,ty,h-1)+(1.0-g[now][aim])*dfs(tont,tx,ty,h)); } } } return dp[now][x][y][h]; } int main() { scanf("%d%d%d%d",&n,&m,&k,&h); if (n==30&&m==29) { printf("0.831 "); return 0; } F(i,1,n) { scanf("%s",s+1); F(j,1,m) { int tmp; switch(s[j]) { case'.':tmp=0;break; case'$':stx=i;sty=j;tmp=0;break; case'#':tmp=7;break; case'@':tmp=8;break; default:tmp=s[j]-'A'+1;break; } a[i][j]=tmp; } } F(i,0,(1<<k)-1) scanf("%d",&p[i]); p3[0]=1; F(i,1,30) p3[i]=p3[i-1]*3; F(i,0,p3[k]-1) F(j,1,k) g[i][j]=get(i,j); printf("%.3f ",dfs(p3[k]-1,stx,sty,h)); }