http://codeforces.com/contest/596/problem/D

题目大意:

有n棵树排成一排,高度都为h.

主人公要去砍树,每次等概率地随机选择没倒的树中最左边的树或者最右边的树把它砍倒.每棵树被砍到后,有p的概率会往左边倒,(1-p)的概率往右边倒.

树倒下后如果压到别的树,即如果那棵树倒下的方向上距离不到h的地方还有一棵树,,那么那棵树也会朝和这个树相同的方向倒下.

问最后所有的树都被砍完后覆盖的地面的长度的期望.

思路:dp[i][j][0/1][0/1]代表i到j这个区间,i-1的状态是0/1,j+1的状态是0/1的长度期望

我们每次只求当前倒下树增加的期望.

转移比较复杂:

当l=r时,判断有没有被左右某棵树压倒,有那就直接取这样做的贡献

否则我们要算上概率,p往左倒,1-p往右倒

当l不等于r时,我们有最左边和最右边的两棵树的选择,同样看一下有没有被外层的某棵树压倒,压倒就直接算,否则我们考虑往左和往右倒的概率,以及选最左边和最右边的概率。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ll long long
ll a[];
bool vis[][][][];
double f[][][][];
int n;
ll h;
double p;
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
double dp(int l,int r,int sl,int sr){
if (vis[l][r][sl][sr]) return f[l][r][sl][sr];
vis[l][r][sl][sr]=;
f[l][r][sl][sr]=;
if (l==r){
if (sl==&&a[l-]+h>a[l]){
if (sr) return f[l][r][sl][sr]=std::min(h,a[l+]-a[l]);
else return f[l][r][sl][sr]=std::min(h,std::max(0LL,a[l+]-a[l]-h));
}else
if (sr==&&a[r+]-h<a[r]){
if (sl==) return f[l][r][sl][sr]=std::min(h,a[l]-a[l-]);
else return f[l][r][sl][sr]=std::min(h,std::max(0LL,a[l]-a[l-]-h));
}
double ans=;
if (sl)
ans+=p*std::min(h,std::max(0LL,a[l]-a[l-]-h));
else
ans+=p*std::min(h,a[l]-a[l-]);
if (sr==)
ans+=(1.0-p)*std::min(h,std::max(0LL,a[l+]-a[l]-h));
else
ans+=(1.0-p)*std::min(h,a[l+]-a[l]);
return f[l][r][sl][sr]=ans;
}
if (sl==&&a[l-]+h>a[l])
return f[l][r][sl][sr]=dp(l+,r,,sr)+std::min(h,a[l+]-a[l]);
else
if (sr==&&a[r+]-h<a[r])
return f[l][r][sl][sr]=dp(l,r-,sl,)+std::min(h,a[r]-a[r-]);
double ans=;
ans+=0.5*(-p)*(dp(l+,r,,sr)+std::min(h,a[l+]-a[l]));
ans+=0.5*(p)*(dp(l,r-,sl,)+std::min(a[r]-a[r-],h));
if (sl==)
ans+=0.5*p*(dp(l+,r,,sr)+std::min(h,std::max(0LL,a[l]-a[l-]-h)));
else
ans+=0.5*(p)*(dp(l+,r,,sr)+std::min(h,a[l]-a[l-])); if (sr==)
ans+=0.5*(-p)*(dp(l,r-,sl,)+std::min(h,std::max(0LL,a[r+]-a[r]-h)));
else
ans+=0.5*(-p)*(dp(l,r-,sl,)+std::min(h,a[r+]-a[r]));
return f[l][r][sl][sr]=ans;
}
int main(){
n=read();h=read();scanf("%lf",&p);
for (int i=;i<=n;i++) a[i]=read();
std::sort(a+,a++n);
a[]=a[]-1e10;a[n+]=a[n]+1e10;
printf("%.9f\n",dp(,n,,));
}

Codeforces 596D Wilbur and Trees的更多相关文章

  1. Codeforces 596D Wilbur and Trees dp (看题解)

    一直在考虑, 每一段的贡献, 没想到这个东西能直接dp..因为所有的h都是一样的. #include<bits/stdc++.h> #define LL long long #define ...

  2. Codeforces Round #331 (Div. 2) D. Wilbur and Trees 记忆化搜索

    D. Wilbur and Trees Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/596/p ...

  3. Codeforces 9D How many trees? 【计数类DP】

    Codeforces 9D How many trees? LINK 题目大意就是给你一个n和一个h 问你有多少个n个节点高度不小于h的二叉树 n和h的范围都很小 感觉有无限可能 考虑一下一个很显然的 ...

  4. Codeforces 545E. Paths and Trees 最短路

    E. Paths and Trees time limit per test: 3 seconds memory limit per test: 256 megabytes input: standa ...

  5. CodeForces #369 C. Coloring Trees DP

    题目链接:C. Coloring Trees 题意:给出n棵树的颜色,有些树被染了,有些没有.现在让你把没被染色的树染色.使得beauty = k.问,最少使用的颜料是多少.   K:连续的颜色为一组 ...

  6. codeforces 711C C. Coloring Trees(dp)

    题目链接: C. Coloring Trees time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. Codeforces 711 C. Coloring Trees (dp)

    题目链接:http://codeforces.com/problemset/problem/711/C 给你n棵树,m种颜色,k是指定最后的完美值.接下来一行n个数 表示1~n树原本的颜色,0的话就是 ...

  8. codeforces 633G. Yash And Trees dfs序+线段树+bitset

    题目链接 G. Yash And Trees time limit per test 4 seconds memory limit per test 512 megabytes input stand ...

  9. Codeforces - 9D - How many trees? - 简单dp - 组合数学

    https://codeforces.com/problemset/problem/9/D 一开始居然还想直接找公式的,想了想还是放弃了.原来这种结构是要动态规划. 状态是知道怎么设了,$t_{nh} ...

随机推荐

  1. 8.2.1.1 Speed of SELECT Statements 加速SELECT 语句

    8.2.1 Optimizing SELECT Statements 8.2.2 Optimizing Data Change Statements 8.2.3 Optimizing Database ...

  2. 【转】VS2013中如何解决error C4996: 'fopen'问题

    原文网址:http://jingyan.baidu.com/article/ce436649fd61543773afd32e.html 今天编写控制台应用程序时出现如下错误 error C4996: ...

  3. android 在EditText中显示表情图片

    public class MainActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { su ...

  4. js-权威指南学习笔记4

    第五章 语句 1.在JS中没有块级作用域,在语句块中声明的变量并不是语句块私有的. 2.尽管函数声明语句和函数定义表达式具有相同的函数名,但二者仍然不同.两种方式都创建了新的函数对象,但函数声明语句中 ...

  5. cocoapods 的使用心得

    一般我们下载的demo里边含有cocoapods 我们需要 在终端上输入命令,让他能够成功运行 步骤如下: 打开终端  cd 项目目录  直接拖动到终端里边就可以, 然后 pod install 如果 ...

  6. Gulp-livereload:实时刷新编码

    实现功能 监听指定目录下的所有文件,实时动态刷新页面 安装(Install) 功能的实现是借助 gulp-connect 插件完成的;所以,首先通过下面命令完成插件安装: npm install -- ...

  7. struts2讲义----二

    Struts的namespace 示例工程Struts2_0200_Namespace Struts.xml <struts> <constant name="struts ...

  8. Java基础知识强化58:经典排序之二叉树排序(BinaryTreeSort)

    1. 二叉树排序 二叉树排序的描述也是一个递归的描述, 所以二叉树排序的构造自然也用递归的: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它 ...

  9. Append加载动态轮播

    前几天遇到了些小麻烦,不过很快就解决了.之所以要记下来是因为作为一名前端的程序员,要理解页面的加载顺序是最重要的.要不然自己写程序意外的出现bug~~ 刚开始写利用Append的时候,利用火狐的fir ...

  10. RecyclerView 详解

    概述 RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用.  据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件 ...