●BZOJ 4318 OSU!

题链:

http://www.lydsy.com/JudgeOnline/problem.php?id=4318
题解:

期望dp
如果我们能够得到以每个位置结尾形成的连续1的长度的相关期望,那么问题就好解决了。

定义g[i]表示以1位置结尾的连续1的长度的期望。
转移显然:g[i]=p[i]*(g[i]+1)
然后定义h[i]表示以1位置结尾的连续1的长度的平方的期望
由于(x+1)^2=x^2+2x+1,
所以h[i]=p[i]*(h[i-1]+2*g[i-1]+1)

最后定义f[i]表示1~i这个区间期望能得到的分数,
分为此时i位置得到1和得到0两种情况:
得到1,由于(x+1)^3=x^3+3*x^2+3x+1 那么贡献为:p[i]*(f[i-1]+3*h[i-1]+3*g[i-1]+1)
得到0,那么直接为前面的期望得分,贡献为(1-p[i])*f[i-1]
所以f[i]的转移为:f[i]=(得到1)p[i]*(f[i-1]+3*h[i-1]+3*g[i-1]+1)+(得到0)(1-p)*f[i-1];

.....................................................................

==,难道没有感觉这个f[i]的转移有一丝丝诡异么?
先看看这个错的做法,
多了一个d[i],表示以i结尾形成的连续1的长度的3次方的期望。
那么其转移类似g和h的转移:
d[i]=p[i]*(d[i-1]+3*h[i-1]+3*g[i-1]+1)
然后再去求得f[i],同样地分为当前第i位得到1和得到0两种情况:
f[i]=(得到1)d[i]+(得到0)(1-p[i])*f[i-1]

乍一看似乎没问题,但是在(得到1)那里却出了问题:
f[i]表示的是1~i这个区间期望能够得到的分数,
但是在(得到1)这个转移这里,我们却只考虑了以i结尾的期望的那段1的贡献,然而其它部分的贡献就没有转移过来。
这也就是这个做法得到的答案比正确答案小的原因。
(可以强行把之前的贡献再加进来么?233,我反正加不来。。。)

.......................................................................

现在再反过来看看之前正确的f[i]的求法(没有d[i]数组的那个做法)
f[i]=(得到1)p[i]*(f[i-1]+3*h[i-1]+3*g[i-1]+1)+(得到0)(1-p)*f[i-1];

显然(得到0)的那个转移没有问题。

那么我们来想想(得到1)的那么那个转移是如何解决掉那个错误做法出现的问题的。
由于f[i-1]表示的是区间1~i-1的期望得分,
那么我们就可以把f[i-1]看成是由两个部分组成的:
一个部分是以i-1结尾的期望的那段连续的1造成的贡献A(一个长度的3次方的期望),另一部分则是其它部分的贡献B:
所以(得到1)这个转移可以看成是:p[i]*(B+A+3*h[i-1]+3*g[i-1]+1),
显然,后面的A+3*h[i-1]+3*g[i-1]+1计算的就是以i结尾形成的连续1的长度的3次方的期望,
而B则是其它部分的贡献。
所以就是这样巧妙地把新的贡献和其它部分的贡献都统计进了f[i]里面。

以上就是个人的见解。

代码:

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
double g[MAXN],h[MAXN],f[MAXN],p;
int N;
int main(){
	ios::sync_with_stdio(0);
	cin>>N;
	for(int i=1;i<=N;i++){
		cin>>p;
		g[i]=p*(g[i-1]+1);
		h[i]=p*(h[i-1]+2*g[i-1]+1);
		f[i]=p*(f[i-1]+3*h[i-1]+3*g[i-1]+1)+(1-p)*f[i-1];
	}
	cout<<fixed<<setprecision(1)<<f[N]<<endl;
	return 0;
}

  

原文地址:https://www.cnblogs.com/zj75211/p/8543018.html

时间: 2024-11-10 07:17:16

●BZOJ 4318 OSU!的相关文章

BZOJ 4318: OSU!

Description osu 是一款群众喜闻乐见的休闲软件. 我们可以把osu的规则简化与改编成以下的样子: 一共有n次操作,每次操作只有成功与失败之分,成功对应1,失败对应0,n次操作对应为1个长度为n的01串.在这个串中连续的 X个1可以贡献X^3 的分数,这x个1不能被其他连续的1所包含(也就是极长的一串1,具体见样例解释) 现在给出n,以及每个操作的成功率,请你输出期望分数,输出四舍五入后保留1位小数. Input 第一行有一个正整数n,表示操作个数.接下去n行每行有一个[0,1]之间

[BZOJ 4318]OSU!(期望dp)

Description osu 是一款群众喜闻乐见的休闲软件. 我们可以把osu的规则简化与改编成以下的样子: 一共有n次操作,每次操作只有成功与失败之分,成功对应1,失败对应0,n次操作对应为1个长度为n的01串.在这个串中连续的 X个1可以贡献X^3 的分数,这x个1不能被其他连续的1所包含(也就是极长的一串1,具体见样例解释) 现在给出n,以及每个操作的成功率,请你输出期望分数,输出四舍五入后保留1位小数. Solution 和上一题差不多…双倍经验~ 平方的期望并不等于期望的平方,所以还

BZOJ 4318: OSU! [DP 概率]

传送门 题意:变成了告诉每个操作的成功概率,并且得分是三次方 一样....分别维护$x,\ x^2,\ x^3$的期望就行了 注意$x^3$是我们最终求的得分,即使失败得分也要累加上之前的 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long l

BZOJ 4318: OSU! 期望概率dp

这道15行的水题我竟然做了两节课...... 若是f[i][0]=(1-p)*f[i][0]+(1-p)*f[i][1],f[i][1]=p*(f[i-1][0]+1.0)+p*(f[i-1][1]+OOXX); 我们合并一下f[i]=p*1.0+p*OOXX=p*OX; OX:就是期望x^3的差,也就是(x+1)^3=x^3+3*x^2+3*x+1.0,中的3*x^2+3*x+1.0,这样我们要维护x^2以及x注意这里的x^2和x是指结尾的长度x #include<cstdio> doubl

【BZOJ】4318: OSU!

[算法]期望DP [题解] OSU!(误) 原本在纠结长度很不好算啊--x有好多种可能,新增一个不知道加多少QAQ 后来发现我们不是在算期望嘛--不是就算期望长度就好了嘛. f[i]为加入第i个后的收益. g[i]为加入第i个后的期望长度. 加入一个i=1的收益为x^3-(x-1)^3=3x^2-3x+1 注意不能直接g[i]*g[i]表示平方,因为平方不是线性运算,期望的平方≠平方的期望. g2[i]为期望长度的平方. 推导方式中(x-1)--->x和x--->(x+1)的区别: 我们设置g

一句话题解(持续更新中)

8.1 bzoj 4720 noip2016 换教室 floyd预处理+期望(薛定谔的猫) bzoj 4318 OSU! 三次函数期望值 从一次.二次推得 8.2 bzoj 1076 状压+期望DP 逆拓扑序(贪心常用手段防止现在过度影响未来)lim边界问题曾WA多次 bzoj 1012 树状数组(线段树)第二 暴力更新后缀第一(明显可卡) 暴力查询要TLE 单调栈没调出来 //bzoj 1010 toys玩具装箱 单调性 //bzoj 1006 弦图染色裸题 诱导子图.完全图.团.最小染色.最

●Joyoi Easy

题链: http://www.joyoi.cn/problem/tyvj-1952题解: 概率dp (先做的BZOJ 4318: OSU!,然后就感觉这个题很简单了) 链接: 令p[i]表示第i个位置为o的概率. 定义g[i]表示以i位置结尾形成1的期望长度 g[i]=p[i]*(g[i-1]+1) 在定义f[i]表示从1到i位置的期望得分, 分为i位置为o和为x两种情况 f[i]=p[i]*(f[i-1]+2*g[i-1]+1)+(1-p)*f[i-1] 代码: #include<bits/s

OSU!

4318: OSU! Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 748  Solved: 579 [Submit][Status][Discuss] Description osu 是一款群众喜闻乐见的休闲软件. 我们可以把osu的规则简化与改编成以下的样子: 一共有n次操作,每次操作只有成功与失败之分,成功对应1,失败对应0,n次操作对应为1个长度为n的01串.在这个串中连续的 X个1可以贡献X^3 的分数,这x个1不能被其他连续的1所包含

bzoj4318: OSU!&amp;&amp;CF235BLet&#39;s Play Osu!

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4318 4318: OSU! Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 374  Solved: 294[Submit][Status][Discuss] Description osu 是一款群众喜闻乐见的休闲软件. 我们可以把osu的规则简化与改编成以下的样子: 一共有n次操作,每次操作只有成功与失败之分,成功对应1,失败对应0,n次