[USACO18DEC]Balance Beam P
根据题意不难发现这个模型是不好进行贪心的,于是可以考虑使用 \(dp\)。可以令 \(dp_i\) 表示在 \(i\) 位置以最优策略能获得的报酬期望值,那么会有转移:
\]
不难发现上面这个 \(dp\) 的转移是有后效性的,但类似地往两边的转移方式在 [六省联考2017]分手是祝愿 中遇到过。但可以发现的是,在那道题的第一个方法当中因为我们终点都是同一个位置所以才可以改变状态向同一边转移,在本题当中这种方法显然是不可取的。
那么另一种方法能否使用呢?你会发现这样一个事实,我们找到 \(i\) 左侧第一个停下来更优的位置记作 \(l\),右侧第一个停下来更优的位置记作 \(r\)。那么 \([l, r]\) 中的位置向左向右都只会走到 \(l, r\) 然后停止,于是我们可以使用第二种方法来观察一下这一段转移的特色。
首先会有:
\]
那么一般地,会有:
\]
同时需要注意到 \(dp_r = f_r\),则会有:
\]
类似于前面的归纳方式,同理可以得到:
\]
貌似这样还是看不出有什么特别之处,那么可以尝试将假设进一步特殊化。就令 \(l = 0, r = n\) 尝试一下,那么会发现:
\]
这不恰好是一个正比例函数的形式吗?即 \(y = \dfrac{f_n}{n} \times i\) 的形式。那么是不是最上面哪个也会是某个一次函数呢?可以考虑能否将 \(dp\) 转移方程化简成一次函数的形式,不难发现可以整理成如下形式:
\]
可以看出这就是将直线 \(y = \dfrac{f_r - f_l}{r - l}x + f_l\) 向右平移 \(l\) 个单位所得直线,也就是 \((l, f_l), (r, f_r)\) 所连成的直线。那么我们惊喜地发现,以 \(l, r\) 为停下左右端点对中间每个点 \(i\) 的贡献为 \(i\) 在 \((l, f_l), (r, f_r)\) 上 \(i\) 位置对应的纵坐标。那么结合图像可以发现为了使得答案最优,不会存在任意一个点 \(i\) 其 \(f_i\) 大于在其在直线上的纵坐标。回过头来整体地看,这所有的直线连成的一个图形不恰好是 \((i, f_i)\) 所形成的凸包吗?于是我们只需求出这 \(n\) 个点的凸包然后在上面求答案即可。因为 \(f_i > 0\) 因此只需使用类似斜率优化的方法求凸包即可。时间复杂度 \(O(n)\)。
因为本题卡精度,所以只能使用和 \(std\) 一样的输出方式才能通过 TAT。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i, l, r) for (int i = l; i <= r; ++i)
const int N = 100000 + 5;
int n, top, f[N], st[N], ans[N];
int read() {
char c; int x = 0, f = 1;
c = getchar();
while (c > '9' || c < '0') { if(c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
double slope(int a, int b) {
return 1.0 * (f[a] - f[b]) / (a - b);
}
signed main(){
n = read();
rep(i, 1, n) f[i] = read();
rep(i, 0, n + 1) {
for (; top > 1 && slope(st[top - 1], i) > slope(st[top - 1], st[top]); --top) ;
st[++top] = i;
}
rep(i, 1, top - 1) {
int j = st[i];
for(; j <= st[i + 1]; ++j)
ans[j] = 100000ll * (f[st[i]] * (st[i + 1] - j) + f[st[i + 1]] * (j - st[i])) / (st[i + 1] - st[i]);
}
rep(i, 1, n) printf("%lld\n", ans[i]);
return 0;
}
值得一提的是,这种放宽条件特殊化的方法在本题当中反复出现。极端情况找规律这种思想也扮演着不可或缺的角色。
[USACO18DEC]Balance Beam P的更多相关文章
- 洛谷P5155 [USACO18DEC]Balance Beam(期望,凸包)
你以为它是一个期望dp,其实它是一个凸包哒! 设平衡木长度为\(L\),把向右走平衡木那个式子写一下: \[dp[i]=\frac{dp[i+1]+dp[i-1]}{2}\] 然后会发现这是一个等差数 ...
- Luogu5155 [USACO18DEC]Balance Beam
题目链接:洛谷 这道题看起来是个期望题,但是其实是一道计算几何(这种题太妙了) 首先有一个很好的结论,在一个长度为$L$的数轴上,每次从$x$处出发,不停地走,有$\frac{x}{L}$的概率从右端 ...
- [USACO18DEC]Balance Beam
题目链接:这里 或者这里 答案是很显然的,记\(g(i)\)为在\(i\)下平衡木时的期望收益 那么\(g(i)=max(f(i),\frac{g(i-1)+g(i+1)}{2})\) 好了做完了 T ...
- 题解-USACO18DEC Balance Beam详细证明
(翻了翻其他的题解,觉得它们没讲清楚这个策略的正确性) Problem 洛谷5155 题意概要:给定一个长为\(n\)的序列,可以选择以\(\frac 12\)的概率进行左右移动,也可以结束并得到当前 ...
- Luogu5155 USACO18DEC Balance Beam(概率期望+凸包)
假设已经求出了在每个点的最优期望收益,显然最优策略是仅当移动一次后的期望收益>当前点收益时移动.对于初始点,其两边各存在一个最近的不满足上述条件的位置,因此从初始点开始随机游走,直到移动到这两个 ...
- p5155 [USACO18DEC]Balance Beam
传送门 分析 https://www.luogu.org/blog/22112/solution-p5155 代码 #include<bits/stdc++.h> using namesp ...
- 题解 [USACO18DEC]Balance Beam
被概率冲昏的头脑~~~ 我们先将样例在图上画下来: 会发现,最大收益是: 看出什么了吗? 这不就是凸包吗? 跑一遍凸包就好了呀,这些点中,如果i号点是凸包上的点,那么它的ans就是自己(第二个点),不 ...
- bzoj5483: [Usaco2018 Dec]Balance Beam
又又又又又又又被踩爆了 首先容易写出这样的期望方程:f(1)=max(d(1),f(2)/2),f(n)=max(d(n),f(n-1)/2), f(i)=max(d(i),(f(i-1)+f(i+1 ...
- 当PsychicBoom_发觉自己是个大SB的时候……
这些题都是没ac调了好久发现是sb错误的题--. 想清楚再写题!!! 2019.4.18 洛谷P5155 [USACO18DEC]Balance Beam 转移方程\((a[l[i]]*(r[i]-i ...
随机推荐
- Proximal Algorithms 7 Examples and Applications
目录 LASSO proximal gradient method ADMM 矩阵分解 ADMM算法 多时期股票交易 随机最优 Robust and risk-averse optimization ...
- Mysql数据库语言学习的路线
对于我们数据库的学习,不管是测试人员还是开发人员以及我们的DBA来说重点都是SQL:但是我们的SQL可以分多少类型,学习重点又是在哪里呢,本文仅仅针对测试人员来展开说明: SQL:structure ...
- Eclipse远程调试Java代码的三种方法
Eclipse远程调试Java代码的三种方法, 第1种方法是用来调试已经启动的Java程序,Eclipse可以随时连接到远程Java程序进行调试, 第2种方法可以调试Java程序启动过程,但是Ecli ...
- 记一次log4j2引发的渗透测试
前言 记一次log4j2打入内网并用CVE-2021-42287.CVE-2021-42278获取到DC权限的靶场渗透. 外网打点 首先对web进行端口扫描,发现38080端口和22端口 访问一下38 ...
- 使用.NET 6开发TodoList应用(21)——实现API版本控制
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 API接口版本管理,对于一些规模稍大的企业应用来说,是经常需要关注的一大需求.尽管我们的示例程序TodoList很简单,但是我 ...
- python 自动化测试框架unittest与pytest的区别
前言: 有使用过unittest单元测试框架,再使用pytest单元测试框架,就可以明显感觉到pytest比unittest真的简洁.方便很多. unittest与pytest的区别: 主要从用例编写 ...
- python 报错:RecursionError: maximum recursion depth exceeded
RecursionError:maximun recursion depth exceeded 超过了最大递归深度 原因: 在使用@property装饰器时,方法名与实例的属性同名,在赋值进从而产生了 ...
- unittest_expectedFailure预期用例失败(5)
在断言用例执行结果时,会出现预期结果与实际结果不一致的情况,此时我们明确知道用例执行结果为FAIL,不想看到打印错误信息怎么办? 使用装饰器@unittest.expectedFailure标记该用例 ...
- [Win32] UAC用户账户控制 (提权)
最近写程序时遇到一个问题,就是当一个程序需要管理员权限才能正常运行该怎么办? 通过查阅多方资料,我总结出来几个比较实用的办法(每种办法实现方法不同,同时功能上也有一些小小的差异) 方法一(批处理脚本) ...
- Visual Studio 2015 MFC之Button颜色变化-断点调试(Debug)
软件开发,对自己的程序进行调试很重要,本次文章在上一边随笔的基础上,介绍一下Button控件做显示灯的用法,Button控件的添加和变量设置等可以参考下面的的链接:Visaul Studio 2015 ...