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. java调优随记-java对象大小

    在java中,基本数据类型的大小是固定.但是java对象的大小是不固定的,需要通过计算. 在java中,一个空对象(没有属性和方法的对象)在堆中占用8byte,比如 Object obj = new ...

  2. Git Bash下实现复制粘贴等快速编辑功能

    在windows下使用Git Bash会经常用到选中.复制.粘贴等功能,但是一般用的方法会很复杂,笔者经过查阅一些资料,特整理一些常见编辑功能的实现方法. (1)默认方法: 单击左上角的logo ic ...

  3. Android豆瓣图书查询Demo

    原文出自:方杰| http://fangjie.info/?p=26 转载请注明出处 首先先看一下Demo预览效果吧,主要也就是两个Activity.涉及到的技术有zxing开源项目的使用,网络协议豆 ...

  4. Nginx缓存解决方案:SRCache

    前些天帮别人优化PHP程序,搞得灰头土脸,最后黔驴技穷开启了FastCGI Cache,算是勉强应付过去了吧.不过FastCGI Cache不支持分布式缓存,当服务器很多的时候,冗余的浪费将非常严重, ...

  5. windows 删除服务命令

    在dos窗口下执行 sc delete  服务名( 例如 mysql) C:\Program Files\MySQL\MySQL Server 5.6\

  6. IOS-UITableView开发常用各种方法总结

    实现列表有两种方式 方式一 继承UIViewController,实现UITableViewDataSource和UITableViewDelegate协议.声明UITableView. UserIn ...

  7. angularJS怎么实现与服务端的PHP进行数据交互

    //{params: 要传的参数obj },params这个是关键字不能换别的变量 $http.get(url, {params: {id: categoryid, key: keys} }).suc ...

  8. repo简介

    高通的Android JellyBean库已经建立完成,目前已经可以正常访问,可以正常提交.Repo获取代码注意:1. 首先应有一个repo脚本,并将脚本放到环境变量里,此脚本的配置方法a) 进入用户 ...

  9. Linux编程环境介绍(2) -- shell(Bash) 介绍

    1. 在计算机科学中,Shell俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器).它类似于DOS下的command和后来的cmd.exe. 2. bash (Bourne Aga ...

  10. 关于SQL中数据类型(float和real)和 .NET Framework 中数据类型(float和double)的问题

    今天同学写程序遇到一个问题,MSSQL里的数据是 float 类型,在 .NET Framework 中用的时候也转换成 float 类型,结果报错,类型转换异常,明明是相同的类型,为什么会异常 在w ...