HDU 4405(概率dp入门)

说是概率DP,其实主要是求概率和期望的问题

说到DP总要有状态,每种状态可能有多种子状态

一般的DP是这样:在DP过程中,当前状态必然是由多个子状态中的最优的转移而来

所以一般的DP求的是最优的结果

而概率不需要最优,而是实际概率

所以概率DP最大的区别在于:在DP过程中,当前状态是由所有子状态的概率共同转移而来

所以概率DP只是利用了DP的动态而没有规划 (只有状态转移,而不需要进行决策)

转载自: https://blog.csdn.net/tomorrowtodie/article/details/52336931

Aeroplane chess

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5665    Accepted Submission(s): 3541


 

Problem Description

Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal probability to face up and the numbers on the faces are 1,2,3,4,5,6). When Hzz is at grid i and the dice number is x, he will moves to grid i+x. Hzz finishes the game when i+x is equal to or greater than N.

There are also M flight lines on the chess map. The i-th flight line can help Hzz fly from grid Xi to Yi (0<Xi<Yi<=N) without throwing the dice. If there is another flight line from Yi, Hzz can take the flight line continuously. It is granted that there is no two or more flight lines start from the same grid.

Please help Hzz calculate the expected dice throwing times to finish the game.

 

Input

There are multiple test cases.
Each test case contains several lines.
The first line contains two integers N(1≤N≤100000) and M(0≤M≤1000).
Then M lines follow, each line contains two integers Xi,Yi(1≤Xi<Yi≤N).  
The input end with N=0, M=0.

 

Output

For each test case in the input, you should output a line indicating the expected dice throwing times. Output should be rounded to 4 digits after decimal point.

 

Sample Input

2 0

8 3

2 4

4 5

7 8

0 0

 

Sample Output

1.1667

2.3441

设dp[i] 为从第i个点到终点需要投掷的次数,

那么 dp[i] = ∑(j = 1, 6)dp[i+j]*p(j) + 1  ,   其中p(j) 为投掷结果为 j 的概率, + 1 是因为从此一步到下一步 一定会 投掷一次

AC代码:

#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 100050;
double dp[maxn];
int h[maxn];

int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        if(!n && !m) break;
        memset(dp,0,sizeof(dp));
        memset(h,0,sizeof(h));
        int x,y;
        for(int i = 0;i < m;i ++){
            scanf("%d%d",&x,&y);
            h[x] = y;
        }
        for(int i = n - 1;i >= 0;i --){
            if(h[i]) dp[i] = dp[h[i]];
            else {
                for(int j = 1;j <= 6;j ++)
                    dp[i] += 1.0/6 * dp[i+j];
                dp[i] += 1;
            }
        }
        printf("%.4lf\n",dp[0]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/no_o_ac/article/details/81151909