HDU 3853 LOOPS [簡單概率DP]

Description

Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl). 

Homura wants to help her friend Madoka save the world. But because of the plot of the Boss Incubator, she is trapped in a labyrinth called LOOPS. 

The planform of the LOOPS is a rectangle of R*C grids. There is a portal in each grid except the exit grid. It costs Homura 2 magic power to use a portal once. The portal in a grid G(r, c) will send Homura to the grid below G (grid(r+1, c)), the grid on the right of G (grid(r, c+1)), or even G itself at respective probability (How evil the Boss Incubator is)! 
At the beginning Homura is in the top left corner of the LOOPS ((1, 1)), and the exit of the labyrinth is in the bottom right corner ((R, C)). Given the probability of transmissions of each portal, your task is help poor Homura calculate the EXPECT magic power she need to escape from the LOOPS. 

題意:給出一個矩陣,每個點每一步有P0的概率在原點,P1的概率向右走,P2的概率向左走,問從左上角走到右下角的期望步數。

解法:很簡單很明顯的概率DP,DP[I][J]表示當前在I,J,走到右下角的期望步數,那麼轉移方程爲:

DP[I][J]=(DP[I][J+1]*P1+DP[I+1][J]*P2)/(1-P0)

注意1-P0爲0的時候,會是0/0的情況,應該返回0,否則計算的時候會出錯,具體坑點看代碼。


代碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){ //Faster Input
    char c; int sgn; T bit=0.1;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    if(c==' '||c=='\n'){ ret*=sgn; return 1; }
    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
    ret*=sgn;
    return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

double p[1010][1010][3];
double dp[1010][1010];
bool vis[1010][1010];
int n,m;
double dfs(int i,int j){
    if(j>m||i>n||i==n&&j==m)return 0;
    if(vis[i][j])return dp[i][j];
    vis[i][j]=1;
    dp[i][j]=2.0;
    //必須保證有概率走過去,否則那些點肯定不用走
    //那些點有可能一直在本身循環,導致答案錯誤,產生0/0的情況
    if(p[i][j][1]>0.0)dp[i][j]+=p[i][j][1]*dfs(i,j+1);
    if(p[i][j][2]>0.0)dp[i][j]+=p[i][j][2]*dfs(i+1,j);
    dp[i][j]/=(1.0-p[i][j][0]);
    return dp[i][j];
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        rep(i,1,n)rep(j,1,m){
            vis[i][j]=0;
            scanff(p[i][j][0]);
            scanff(p[i][j][1]);
            scanff(p[i][j][2]);
        }
        double ans=dfs(1,1);
        printf("%.3f\n",ans);
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章