uva 10529 - Dumb Bones(概率dp)

Problem D: Dumb Bones

You are trying to set up a straight line of dominos, standing on end, to be pushed over later for your entertainment. (Sure, it seems pointless to set something up only to knock it down again, but you have some strange hobbies) The tricky thing about setting dominos, however, is that if you make a mistake and knock one over as you place it, it will knock down any adjacent line of consecutive dominos on one side of it, partially ruining your work.

For instance, if you've already placed dominos in the pattern DD__DxDDD_D, and you try placing a domino at position x, there is a chance it will fall and knock over the domino to the left or the three dominos to its right, forcing you to place them again.

This human error is somewhat unavoidable, but you can make the odds somewhat more favourable by using a domino-placing technique that leads to dominos falling in one direction more often than in the other.

Given the number of dominos you are trying to set up, and the probability that you'll knock over any individual domino either to the left or to the right while placing it, determine the average number of dominos you'll need to place before you finish. Assume that you're using an optimal placement strategy.

Input will consist of up to 100 cases. Each case consists of one line of input. It will contain the number of dominos to place, n, 1 <= n <= 1000, followed by nonnegative values Pl and Pr, indicating the probability of any domino falling to the left or to the right when placed. You may assume 0 < Pl + Pr <= 0.5.

The last test case is followed by a line containing a single 0.

For each case, output the expected number of dominos that will need to be placed before you finish, accurate to two digits after the decimal.

Sample Input

10 0.25 0.25
10 0.1 0.4
10 0.0 0.5
0

Sample Output

46.25
37.28
20.00

D. Kisman

dp[i]表示构成连续i张牌的期望。枚举构成连续i张牌的最后一张牌的位置,dp[i]取期望最小值。

#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
#include<cmath>
using namespace std;
const int maxn = 1000 + 5;
const int INF = 1000000000;
const double eps = 1e-6;
typedef long long LL;
typedef pair<int, int> P;

double dp[maxn];

int main(){
    int n;
    double pl, pr;
    while(cin >> n){
        if(n == 0) break;
        cin >> pl >> pr;
        dp[1] = 1/(1-pl-pr);
        dp[0] = 0;
        for(int i = 2;i <= n;i++){
            double Min = (double)INF;
            for(int j = 0;j < i;j++){
                int l = j, r = i-j-1;
                double x = (1+pl*dp[l]+pr*dp[r])/(1-pl-pr);
                Min = min(Min, x+dp[l]+dp[r]);
            }
            dp[i] = Min;
        }
        printf("%.2lf\n", dp[n]);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值