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. 【HDOJ】1497 Simple Library Management System

    链表. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXM 1001 #def ...

  2. VS2010发布、打包安装程序

    1. 在vs2010 选择“新建项目”→“ 其他项目类型”→“ Visual Studio Installer→“安装项目”: 命名为:Setup1 . 这是在VS2010中将有三个文件夹, 1.“应 ...

  3. 什么是Ajax? (转载于疯狂客的BLOG)

    Ajax的定义 Ajax不是一个技术,它实际上是几种技术,每种技术都有其独特这处,合在一起就成了一个功能强大的新技术. Ajax包括: XHTML和CSS,使用文档对象模型(Document Obje ...

  4. C++中的string类(2)

    相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...

  5. POJ1017 packets

    Packets Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 48911   Accepted: 16570 Descrip ...

  6. sicily 4379 bicoloring

    题意:输入一个简单(无多重边和自环)的连通无向图,判断该图是否能用黑白两种颜色对顶点染色,使得每条边的两个端点为不同颜色. 解法:由于无自连通节点存在,所以只需进行一次宽搜,遍历所有的点和所有的边,判 ...

  7. 回调函数的意义以及python实现

    因工作需要,最近在学习使用python来解析各种文件,包括xmind,xml,excel,csv等等. 在学习python解析XML的时候看到这样一段话: 3.ElementTree(元素树) Ele ...

  8. 【IIS小技巧】将IIS Express改成可以通过ip地址访问

    通过浏览器访问的是localhost,如果通过手机访问则需要用ip地址,所以要修改IIS Express的配置,允许通过ip地址访问. IIS Express的配置文件默认在C:\Users\User ...

  9. [ES6] WeakMap vs Map

    WeakMap: is a type of Map where only objects can be passed as keys. Primitive data type -- such are ...

  10. (转)Android 判断用户2G/3G/4G移动数据网络

    在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需(要根据用户当前网络情况来做一些调整的,也可以在 App 的设置模块里,让用户自己选择,在 2G ...