uva 10529 - Dumb Bones(概率dp)

动态规划 专栏收录该内容
57 篇文章 0 订阅

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
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值