【YBT2022寒假Day9 A】最小划分(wqs二分)(斜率优化DP)

最小划分

题目链接:YBT2022寒假Day9 A

题目大意

给你一个序列,你要把它划分成 m 个连续的段,以最小化这个东西:
把每一段的数和表示为 w[i],则要最小化每个 (w[i]+p)^2 的和。

思路

首先你发现这个 p 是没有关系的,你完全可以把它拆开来。
变成 p2m+2snp
si 是前缀和,下同)

首先我们考虑 DP:
fi,j 为当前第 i 个数,划分成了 m 段落。
fi,j=mink=0i1fk,j1+(sisk+p)2

然后我们考虑能不能斜率优化(看着就很斜率优化)。
显然这里我们可以做 m 次斜率优化来达到 O(nm) 的复杂度。
(所以下面就不写第二维了,反正都是从 j1 转移到 j,比较的都是 j1 的)
k1k2 优:(k1>k2
fk1+(sisk1)2<fk2+(sisk2)2
fk1+sk122sisk1<fk2+sk222sisk2
si(2sk22sk1)<(fk2+sk22)(fk1+sk12)
si>(fk2+sk22)(fk1+sk12)2sk22sk1

然后我们考虑如何优化掉 j 的那一维。
那这个时候就有一个神奇的东西叫做 wqs 二分。

就是我们考虑转移的时候加上一个费用 C,这个费用我们二分。
那这个费用是为了干什么呢,可以说是为了“平衡”,使得恰好选到 m 个段的时候最优。
然后最后我们再减去这个贡献即可,减去 Cm

然后你会发现斜率优化 DP 的转移没有变。

代码

#include<cstdio> #include<vector> #define ll long long using namespace std; ll n, m, p, a[100501], sta[100501]; ll f[100501], sz[100501]; ll Y(ll x) { return f[x] + a[x] * a[x]; } ll X(ll x) { return 2 * a[x]; } bool check(ll C) { f[0] = 0; sz[0] = 0; f[1] = a[1] * a[1] + C; sz[1] = 1; ll l = 1, r = 2; sta[1] = 0; sta[2] = 1; for (ll i = 2; i <= n; i++) { while (l < r && Y(sta[l]) - Y(sta[l + 1]) > a[i] * (X(sta[l]) - X(sta[l + 1]))) l++; f[i] = f[sta[l]] + (a[i] - a[sta[l]]) * (a[i] - a[sta[l]]) + C; sz[i] = sz[sta[l]] + 1; while (l < r && (Y(i) - Y(sta[r])) * (X(sta[r]) - X(sta[r - 1])) < (Y(sta[r]) - Y(sta[r - 1])) * (X(i) - X(sta[r]))) r--; sta[++r] = i; } return sz[n] <= m; } int main() { // freopen("divide.in", "r", stdin); // freopen("divide.out", "w", stdout); scanf("%lld %lld %lld", &n, &m, &p); for (ll i = 1; i <= n; i++) scanf("%lld", &a[i]), a[i] = a[i - 1] + a[i]; ll l = 0, r = 1e18, re = 0; while (l <= r) { ll mid = (l + r) >> 1; if (check(mid)) re = mid, r = mid - 1; else l = mid + 1; } check(re); printf("%lld", f[n] - re * m + m * p * p + 2 * a[n] * p); return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/YBT2022Day9_A.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示