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[200005];
bool vis[2005][2005][2][2];
double f[2005][2005][2][2];
int n;
ll h;
double p;
int read(){int t=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';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]=1;f[l][r][sl][sr]=0;if (l==r){if (sl==1&&a[l-1]+h>a[l]){if (sr) return f[l][r][sl][sr]=std::min(h,a[l+1]-a[l]);else return f[l][r][sl][sr]=std::min(h,std::max(0LL,a[l+1]-a[l]-h));}elseif (sr==0&&a[r+1]-h<a[r]){if (sl==0) return f[l][r][sl][sr]=std::min(h,a[l]-a[l-1]);else return f[l][r][sl][sr]=std::min(h,std::max(0LL,a[l]-a[l-1]-h));}double ans=0;if (sl)ans+=p*std::min(h,std::max(0LL,a[l]-a[l-1]-h));elseans+=p*std::min(h,a[l]-a[l-1]);if (sr==0)ans+=(1.0-p)*std::min(h,std::max(0LL,a[l+1]-a[l]-h));elseans+=(1.0-p)*std::min(h,a[l+1]-a[l]);return f[l][r][sl][sr]=ans;}if (sl==1&&a[l-1]+h>a[l]) return f[l][r][sl][sr]=dp(l+1,r,1,sr)+std::min(h,a[l+1]-a[l]);elseif (sr==0&&a[r+1]-h<a[r])return f[l][r][sl][sr]=dp(l,r-1,sl,0)+std::min(h,a[r]-a[r-1]);double ans=0;ans+=0.5*(1-p)*(dp(l+1,r,1,sr)+std::min(h,a[l+1]-a[l]));ans+=0.5*(p)*(dp(l,r-1,sl,0)+std::min(a[r]-a[r-1],h));if (sl==1)ans+=0.5*p*(dp(l+1,r,0,sr)+std::min(h,std::max(0LL,a[l]-a[l-1]-h)));else ans+=0.5*(p)*(dp(l+1,r,0,sr)+std::min(h,a[l]-a[l-1]));if (sr==0)ans+=0.5*(1-p)*(dp(l,r-1,sl,1)+std::min(h,std::max(0LL,a[r+1]-a[r]-h)));else ans+=0.5*(1-p)*(dp(l,r-1,sl,1)+std::min(h,a[r+1]-a[r])); return f[l][r][sl][sr]=ans;
}
int main(){n=read();h=read();scanf("%lf",&p);for (int i=1;i<=n;i++) a[i]=read();std::sort(a+1,a+1+n);a[0]=a[1]-1e10;a[n+1]=a[n]+1e10;printf("%.9f\n",dp(1,n,0,1));
}

转载于:https://www.cnblogs.com/qzqzgfy/p/5667594.html

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 596B Wilbur and Array 贪心

    给出原始{ai}={0},{bi}.每次修改{ai..n}+1或-1,求最小操作次数使{ai}=={bi}. 累计相邻两数差即可. 因为差最大10^9,数字有2*10^5,要long long. #i ...

  4. codeforces 596E Wilbur and Strings(DFS)

    题目链接 E. Wilbur and Strings time limit per test 3 seconds memory limit per test 256 megabytes input s ...

  5. codeforces 711 C. Coloring Trees (dp)

    题目:http://codeforces.com/group/1EzrFFyOc0/contest/711/problem/C 题意:有n棵树,m种颜料,部分树有初始颜色,如为0,则没有初始颜色,给树 ...

  6. CF596D Wilbur and Trees

    一.题目 点此看题 luoguluoguluogu讨论里面有翻译哟,自己去看呗 二.解法 只会从两个端点砍树,很容易看出来是区间dpdpdp了,但是一个区间[l,r][l,r][l,r]的lll向左倒 ...

  7. codeforces 596E Wilbur and Strings

    题意:一个矩阵上面有0~9的数字,可以从任意一个格子出发,每次根据格子上的数字会前进到另一个格子(或原地不动),现在给出q个数位串,问是否有走法可以取出这个串(走到格子上的时候可以不取). 思路:发现 ...

  8. CodeForces596D Wilbur and Trees

    题目链接 一个人要去砍一排n棵树,他会等概率选取当前最左边或最右边的树,树有p的概率向左倒,1-p的概率向右倒,给出每棵树在数轴上的位置与树的高度,求树覆盖长度的期望 dp[l][r][lk][rk] ...

  9. CodeForces 596C Wilbur and Points

    先对n个点分类,然后按题意要求构造,构造的时候判断这个点的右上方之前是否有点,判断可以用线段树来操作. #include<cstdio> #include<cstring> # ...

最新文章

  1. 同一天,数学和计算机界“诺奖”分别揭晓
  2. 传承or创新 ?解密分布式数据库自研修炼之路
  3. Windows Phone:如何检查WMAppManifest中的Capability属性
  4. [自制简单操作系统] 4、计时器(线性表实现优化中断)
  5. vue的列表交错过渡
  6. java零基础学习java规划
  7. 普通人赚钱方法,千万别想靠创业,就能一次翻身
  8. zynq阅读文档之通过中断读GPIO输入的编程指导
  9. 【数学建模】基于matlab模拟十字路口车辆通行【含Matlab源码 1106期】
  10. matlab 非均匀采样,非均匀采样信号的频谱分析
  11. 2020中青杯B题股指与国家经济数学建模全过程文档及程序
  12. 典型分布式计算技术的分析和比较
  13. nowcoder20619 禁书目录
  14. JAVA——文件操作(全)
  15. Docker镜像-Docker
  16. 电脑数据丢失如何恢复呢?
  17. 【百度点石(WSDM)】 Retention Rate of Baidu Hao Kan APP Users 小白经验分享
  18. 本地资源检测,特效检测中Overdraw相关问题
  19. POI操作ppt图表完整示例演示
  20. “+智能”与混合云成为战略主线 郑叶来如何解码华为云2018年终总结

热门文章

  1. SpringMVC学习-helloSpringMVC
  2. 筱筱看博客(微信小程序、Lin-ui组件、vant Weapp)
  3. 百度之星 大搬家 递推
  4. flutter 使用MD5加密
  5. 笔试强训48天——day29
  6. 什么东西改善睡眠质量,辅助睡眠好物推荐
  7. Tomat连接MySQL示例
  8. 仿 手机QQ 登录、注册、找回密码、好友列表、QQ状态等功能的实现
  9. php 图片汉字命名_基于php上传图片重命名的6种解决方法的详细介绍
  10. 泰山OFFICE技术讲座:标点关系穷举研究-07