根据题意不难发现这个模型是不好进行贪心的,于是可以考虑使用 \(dp\)。可以令 \(dp_i\) 表示在 \(i\) 位置以最优策略能获得的报酬期望值,那么会有转移:

\[dp_i = \max(f_i, \frac{1}{2}(dp_{i - 1} + dp_{i + 1}))
\]

不难发现上面这个 \(dp\) 的转移是有后效性的,但类似地往两边的转移方式在 [六省联考2017]分手是祝愿 中遇到过。但可以发现的是,在那道题的第一个方法当中因为我们终点都是同一个位置所以才可以改变状态向同一边转移,在本题当中这种方法显然是不可取的。

那么另一种方法能否使用呢?你会发现这样一个事实,我们找到 \(i\) 左侧第一个停下来更优的位置记作 \(l\),右侧第一个停下来更优的位置记作 \(r\)。那么 \([l, r]\) 中的位置向左向右都只会走到 \(l, r\) 然后停止,于是我们可以使用第二种方法来观察一下这一段转移的特色。

首先会有:

\[dp_l = f_l, dp_{l + 1} = \frac{1}{2} f_l + \frac{1}{2} dp_{l + 2}, dp_{l + 2} = \frac{1}{3}f_l + \frac{2}{3}dp_{l + 3}
\]

那么一般地,会有:

\[dp_i = \frac{1}{i - l + 1}f_l + \frac{i - l}{i - l + 1} dp_{i + 1}(l < i < r)
\]

同时需要注意到 \(dp_r = f_r\),则会有:

\[dp_{r - 1} = \frac{1}{r - l} f_l + \frac{r - l - 1}{r - l} f_r
\]

类似于前面的归纳方式,同理可以得到:

\[dp_i = \frac{r - i}{r - l} f_l + \frac{i - l}{r - l} f_r(l < i < r)
\]

貌似这样还是看不出有什么特别之处,那么可以尝试将假设进一步特殊化。就令 \(l = 0, r = n\) 尝试一下,那么会发现:

\[dp_i = \frac{i}{n} f_n(1 \le i < n)
\]

这不恰好是一个正比例函数的形式吗?即 \(y = \dfrac{f_n}{n} \times i\) 的形式。那么是不是最上面哪个也会是某个一次函数呢?可以考虑能否将 \(dp\) 转移方程化简成一次函数的形式,不难发现可以整理成如下形式:

\[dp_i = \frac{f_r - f_l}{r - l} (i - l) + f_l(l < i < r)
\]

可以看出这就是将直线 \(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的更多相关文章

  1. 洛谷P5155 [USACO18DEC]Balance Beam(期望,凸包)

    你以为它是一个期望dp,其实它是一个凸包哒! 设平衡木长度为\(L\),把向右走平衡木那个式子写一下: \[dp[i]=\frac{dp[i+1]+dp[i-1]}{2}\] 然后会发现这是一个等差数 ...

  2. Luogu5155 [USACO18DEC]Balance Beam

    题目链接:洛谷 这道题看起来是个期望题,但是其实是一道计算几何(这种题太妙了) 首先有一个很好的结论,在一个长度为$L$的数轴上,每次从$x$处出发,不停地走,有$\frac{x}{L}$的概率从右端 ...

  3. [USACO18DEC]Balance Beam

    题目链接:这里 或者这里 答案是很显然的,记\(g(i)\)为在\(i\)下平衡木时的期望收益 那么\(g(i)=max(f(i),\frac{g(i-1)+g(i+1)}{2})\) 好了做完了 T ...

  4. 题解-USACO18DEC Balance Beam详细证明

    (翻了翻其他的题解,觉得它们没讲清楚这个策略的正确性) Problem 洛谷5155 题意概要:给定一个长为\(n\)的序列,可以选择以\(\frac 12\)的概率进行左右移动,也可以结束并得到当前 ...

  5. Luogu5155 USACO18DEC Balance Beam(概率期望+凸包)

    假设已经求出了在每个点的最优期望收益,显然最优策略是仅当移动一次后的期望收益>当前点收益时移动.对于初始点,其两边各存在一个最近的不满足上述条件的位置,因此从初始点开始随机游走,直到移动到这两个 ...

  6. p5155 [USACO18DEC]Balance Beam

    传送门 分析 https://www.luogu.org/blog/22112/solution-p5155 代码 #include<bits/stdc++.h> using namesp ...

  7. 题解 [USACO18DEC]Balance Beam

    被概率冲昏的头脑~~~ 我们先将样例在图上画下来: 会发现,最大收益是: 看出什么了吗? 这不就是凸包吗? 跑一遍凸包就好了呀,这些点中,如果i号点是凸包上的点,那么它的ans就是自己(第二个点),不 ...

  8. 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 ...

  9. 当PsychicBoom_发觉自己是个大SB的时候……

    这些题都是没ac调了好久发现是sb错误的题--. 想清楚再写题!!! 2019.4.18 洛谷P5155 [USACO18DEC]Balance Beam 转移方程\((a[l[i]]*(r[i]-i ...

随机推荐

  1. Log4j使用的方法

    一.什么是log4j Log4J是Apache的一个开放源代码的项目.通过使用Log4J,程序员可以控制日志信息输送的目的地,包括控制台,文件,GUI组件和NT事件记录器,也可以控制每一条日志的输出格 ...

  2. cosface: large margin cosine loss for deep face recognition

    目录 概 主要内容 Wang H, Wang Y, Zhou Z, et al. CosFace: Large Margin Cosine Loss for Deep Face Recognition ...

  3. JWT+SpringBoot实战

    往期内容:JWT - 炒焖煎糖板栗 - 博客园 (cnblogs.com) JWT可以理解为一个加密的字符串,里面由三部分组成:头部(Header).负载(Payload).签名(signature) ...

  4. DP转LVDS方案 瑞奇达CS5211替代PS8625方案 CS5211芯片

    PS8625将作为DP或eDP接收器设备出现在视频源中,并将作为LVDS显示面板的LVDS源设备.该设备是一个完全集成的解决方案,不需要外部CPU.内存.时钟基准或电压调节器.PS8625可配置为从显 ...

  5. Mybatis获取自增主键的值

    pojo: public class User { private Integer id; private String name; private String pwd; setter和getter ...

  6. 造轮子-strace(二)实现

    这一篇文章会介绍strace如何工作,再稍微深入介绍一下什么是system call.再介绍一下ptrace.wait(strace依赖的system call).最后再一起来造个轮子,动手用代码实现 ...

  7. Swoole 协程使用示例及协程优先级

    示例一: Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]); Co\run(function () { go(function() { var_dump(fil ...

  8. Django在使用logging日志模块时报错无法操作文件 logging error Permission Error [WinError 32]

    产生原因: 这个问题只会在开发的时候遇到,而且配置是写入到setting.py配置文件,我们定义了日志文件大小,当日志满了的时候,这时候就会遇到这个问题, 因为在使用Pycharm运行django的时 ...

  9. SQLAlchemy(十)

    ORM操作在实际项目中的应用非常多,涉及到的框架也是根据不同的项目有不同的处理模块,不过操作流程和步骤都是大同小异基本没有什么太大变化,唯一需要注意的就是在实际操作过程中你要使用的ORM框架的处理性能 ...

  10. Oracle 五种约束的创建和移除:

    1.主键约束: 创建表的时候就添加: create table table_name (categoryId varchar2(10), categoryName varchar2(30), prim ...