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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值