Codeforces 596D Wilbur and Trees
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的更多相关文章
- Codeforces 596D Wilbur and Trees dp (看题解)
一直在考虑, 每一段的贡献, 没想到这个东西能直接dp..因为所有的h都是一样的. #include<bits/stdc++.h> #define LL long long #define ...
- 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 ...
- Codeforces 9D How many trees? 【计数类DP】
Codeforces 9D How many trees? LINK 题目大意就是给你一个n和一个h 问你有多少个n个节点高度不小于h的二叉树 n和h的范围都很小 感觉有无限可能 考虑一下一个很显然的 ...
- Codeforces 545E. Paths and Trees 最短路
E. Paths and Trees time limit per test: 3 seconds memory limit per test: 256 megabytes input: standa ...
- CodeForces #369 C. Coloring Trees DP
题目链接:C. Coloring Trees 题意:给出n棵树的颜色,有些树被染了,有些没有.现在让你把没被染色的树染色.使得beauty = k.问,最少使用的颜料是多少. K:连续的颜色为一组 ...
- codeforces 711C C. Coloring Trees(dp)
题目链接: C. Coloring Trees time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- Codeforces 711 C. Coloring Trees (dp)
题目链接:http://codeforces.com/problemset/problem/711/C 给你n棵树,m种颜色,k是指定最后的完美值.接下来一行n个数 表示1~n树原本的颜色,0的话就是 ...
- 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 ...
- Codeforces - 9D - How many trees? - 简单dp - 组合数学
https://codeforces.com/problemset/problem/9/D 一开始居然还想直接找公式的,想了想还是放弃了.原来这种结构是要动态规划. 状态是知道怎么设了,$t_{nh} ...
随机推荐
- centos6.5+Django+mysql+nginx+uwsgi
centos6.5+Django+mysql+nginx+uwsgi 1.nginx的安装.这里采用nginx-1.6.0, 建立一个shell脚本然后执行. #!/bin/bash nginx_ve ...
- 【转】中断处理函数中不用disable_irq而用disable_irq_nosync原因
原文网址:http://blog.csdn.net/skyflying2012/article/details/8265869 今天在写触摸屏驱动时在中断处理函数中使用disable_irq关中断发现 ...
- #翻译# 深入JavaScript的Unicode难题(上)
退一步说, JavaScript处理Unicode时有些怪异. 这篇文章会说明JS在Unicode上令人痛苦的部分, 然后提供解决方案, 并说明在未来的ECMAScript6中是如何改善这些问题的. ...
- HDOJ 1303 Doubles(简单题)
Problem Description As part of an arithmetic competency program, your students will be given randoml ...
- HDU_2040——判断亲和数
Problem Description 古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为: 1+2+4+5+10+11+20+22+44+55+110=284. ...
- Storm drpc学习
示例代码: package com.lky.test; import org.apache.commons.logging.Log; import org.apache.commons.logging ...
- 控制反转(IOC)/依赖注入(DI)理解
个人学习笔记,来自Acode. 1.术语 控制反转/反向控制,英文全称“Inversion of Control”,简称IoC. 依赖注入,英文全称“Dependency Injection”,简称D ...
- HTML5 Canvas显示本地图片实例1、Canvas预览图片实例1
1.前台代码: <input id="fileOne" type="file" /> <canvas id="canvasOne&q ...
- 国外十个出名的 upload 上传组件
在日常开发中,我们常会用到很多的组件及共用代码提高我们的开发效率. King MEDIA - $ 17.00 / 11 Sales DNNStore | 6/5/2014 6:06:42 PM| ...
- C++中的析构函数
代码: #include <cstdio> #include <iostream> using namespace std; class A{ public: ~A(){ co ...