题面在这里

题意

放\(n\)个相连的骨牌,每次放的时候有\(pl\)的概率往左倒,有\(pr\)的概率往右倒,骨牌倒的时候可能会打翻左边相邻或者右边相邻的骨牌,并引起连锁反应直到最后一个骨牌旁边没有与之相邻的骨牌为止

例如\(DD\) _ \(DxDD\) _ \(DD\),

如果在\(x\)处放置骨牌,有可能会让左边的一个或者右边的两个一起倒

求期望放置骨牌的次数

\(T\le100,n\le1000,0<pl+pr\le0.5\)

sol

别人家的题解完全看不懂啊...还是自己写一篇吧

首先考虑单独摆一张骨牌成功的期望次数,记作\(E\)

只要往左倒或者往右倒就要重新摆放,即

\[E=1+pl\times(1+pl\times(...)+pr\times(...))+pr\times(1+pl\times(...)+pr\times(...))
\]

\[=1+(pl+pr)\times(1+(pl+pr)\times(1+(pl+pr)\times(...)))
\]

\[=1+(pl+pr)+(pl+pr)^2+(pl+pr)^3+...+(pl+pr)^{\infty}
\]

\[=\frac{1}{1-pl-pr}
\]

这个式子总算化完了.

如果几张骨牌一起放呢?最优策略又是什么?

考虑放最后一张骨牌的时候,肯定只会剩下一个空位。

那么我们分别把左边和右边的骨牌按照最优策略摆好,再把中间的骨牌摆上去就可以了。

而这个位置可以通过枚举得到......

于是设\(f[x]\)表示摆好连续的\(x\)张骨牌的期望步数,那么

\[f[x]=min_{i=0}^{x}{(1+f[i]+f[x-i-1]+[在第(i+1)个位置摆好这张骨牌的期望步数])}
\]

我们把[在第i个位置摆好这张骨牌的期望步数]记作\(g[i]\)

直接求\(g[i]\)难以统计,我们考虑算出每一部分(左边i-1块/中间一块/右边x-i块)的贡献

左边i-1块:

中间的骨牌每次往左倒,左边i-1块都需要重摆,

于是答案为\(f[i-1]\times[骨牌往左倒的期望次数]\),这里

\[[骨牌往左倒的期望次数]=(E-1)\frac{pl}{pl+pr}=\frac{1-pr}{1-pl-pr}
\]

(\(E=\frac{1}{1-pl-pr}\))

(考虑骨牌每次倒地,有\(\frac{pl}{pl+pr}\)的概率往左倒,有\(\frac{pr}{pl+pr}\)的概率往右倒)

中间一块:

上面已经求出,为\(\frac{1}{1-pl-pr}\)

右边x-i块:

同左边i-1块的求法,为\(f[x-i]\times\frac{1-pl}{1-pl-pr}\)

于是$$g[i]=f[i-1]\times\frac{1-pr}{1-pl-pr}+\frac{1}{1-pl-pr}+f[x-i]\times\frac{1-pl}{1-pl-pr}$$

那么就可以求解了~

代码

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int inf=2147483647;
const int mod=1e9+7;
const int N=5010;
const int M=50010*2;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
} il void file(){
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
} int n;
dd f[N],pl,pr;
il void DP(){
for(RG int i=1;i<=n;i++){
f[i]=inf;
for(RG int j=0;j<=i;j++)
f[i]=min(f[i],f[j]*(1-pl)/(1-pl-pr)+f[i-j-1]*(1-pr)/(1-pl-pr)+1/(1-pl-pr));
}
} int main()
{
while(n=read()){
scanf("%lf%lf",&pl,&pr);
DP();printf("%.2lf\n",f[n]);
}
return 0;
}

[UVA 10529]Dumb Bones的更多相关文章

  1. UVA 10529 - Dumb Bones(概率+区间dp)

    UVA 10529 - Dumb Bones option=com_onlinejudge&Itemid=8&category=518&page=show_problem&am ...

  2. UVA 10529 Dumb Bones 可能性dp 需求预期

    主题链接:点击打开链接 题意: 要在一条直线上摆多米诺骨牌. 输入n, l, r 要摆n张排,每次摆下去向左倒的概率是l, 向右倒的概率是r 能够採取最优策略.即能够中间放一段.然后左右两边放一段等, ...

  3. #11 UVA 10529 Dumb Bones

    题意: 放一堆排,每放一张,有pa的概率让左边的全倒,有pb的概率让右边全倒 问在最优策略下,最少要放几张才能摆放出n张 1<=n<=1000 题解: 这题应该还是很经典的 首先是期望部分 ...

  4. UVA 10529 - Dumb Bones (概率dp)

    题目描述 You are trying to set up a straight line of dominos, standing on end, to be pushed over later f ...

  5. Dumb Bones UVA - 10529[多米诺重构]

    Dumb Bones UVA - 10529   来自绿书p176  题意 你试图把一些多米诺骨牌排成直线,然后推倒它们.但是如果你在放骨牌的时候不小心把刚放的骨牌碰倒了,它就会把相临的一串骨牌全都碰 ...

  6. UVA10529 Dumb Bones

    UVA10529 Dumb Bones go to solution 设$f[i]$表示叠$i$个的骨牌的期望 $O(n)$做法 #include<iostream> #include&l ...

  7. Dumb Bones UVA - 10529(概率dp)

    题意: 你试图把一些多米诺骨牌排成直线,然后推倒它们.但是如果你在放骨牌的时候不小心把刚放的骨牌碰倒了,它就会把相临的一串骨牌全都碰倒, 而你的工作也被部分的破坏了. 比如你已经把骨牌摆成了DD__D ...

  8. Dumb Bones(uva 10529)

    题意:给定n,表示要放n个骨牌,每次放下骨牌,有可能向左倒的概率为pl,向右倒的概率为pr,如果倒下,会将那一侧的骨牌全部推倒,可以选择位置先后放骨牌,问说一种放骨牌次数最少的期望是多少. /* 设d ...

  9. 2018.09.09 UVa10529 - Dumb Bones(期望dp)

    传送门 期望dp好题. f[i]表示摆放i个的最小花费,于是f[i]可以从f[j]与f[i-j+1]转移过来了. 代码: #include<bits/stdc++.h> #define N ...

随机推荐

  1. 优雅使用 illuminate/database 包中的 Collection

    优雅使用 illuminate/database 包中的 Collection 或许你很抵抗使用 Laravel , 但是你没有理由不喜欢使用 illuminate/database.这是一个 ORM ...

  2. centos 7 双网卡建网桥脚本实现

    #!/bin/bash interface1=`ls /sys/class/net|grep en|awk 'NR==1{print}'` interface2=`ls /sys/class/net| ...

  3. unbuntu 系统登录华南师范大学校园网的方法

    最近刚装了unbuntu 系统,刚开始网络连接遇到了点小问题,原来是校园网不知道怎么认证,于是向好基友请教了下,得出快捷的方法如下: 下载学校网络的认证客户端,记住位置,一般都是默认下载地址是 Dow ...

  4. eclipse中创建一个maven项目

    1.什么是Maven Apache Maven 是一个项目管理和整合工具.基于工程对象模型(POM)的概念,通过一个中央信息管理模块,Maven 能够管理项目的构建.报告和文档. Maven工程结构和 ...

  5. Servlet中文乱码问题解决办法

    首先对于源jsp网站和servlet里面的字符集要一样,一般支持中文的字符集为UTF-8最好采用这个字符集(除此之外还有gb2312); 对于源jsp文件的代码中需要设置 设置你的page里面的字符集 ...

  6. 高并发关于微博、秒杀抢单等应用场景在PHP环境下结合Redis队列延迟入库

    第一步:创建模拟数据表. CREATE TABLE `test_table` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NUL ...

  7. 上帝之眼APP——实时定位监控、即时通讯

    项目地址 https://github.com/guoyaohua/GodsEYE 开发环境 Android studio 2.3.1 极光推送IM SDK 百度鹰眼SDK 背景介绍 定位监控系统,不 ...

  8. 业余草分享 Spring Boot 2.0 正式发布的新特性

    就在昨天Spring Boot2.0.0.RELEASE正式发布,今天早上在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误, ...

  9. HDU - 4496 City 逆向并查集

    思路:逆向并查集,逆向加入每一条边即可.在获取联通块数量的时候,直接判断新加入的边是否合并了两个集合,如果合并了说明联通块会减少一个,否则不变. AC代码 #include <cstdio> ...

  10. UVA1213

    先打表,再回溯+剪枝 AC代码: #include<cstdio> #include<cstring> #include<cmath> const int maxn ...