【YBT2023寒假Day7 A】出题人(线段树优化DP)

出题人

题目链接:YBT2023寒假Day7 A

题目大意

有一个序列,你要把它分成若干份,每一份的值的和不超过 m,而且每一段最大值的和最小。
输出每段最大值和的最小值。

思路

考虑每次你选的一段是怎样的。
只有两种情况,一种是踩到开头,要么就是你维护一个递减的单调队列,就是里面的值的位置加一。
那我们所需要维护的就只有这些地方,那每次加入值只有单调队列中新出现或者删去的地方值变了,所以均摊修改次数 O(n)
那就可以用线段树维护值,然后直接区间询问来加速转移 DP。

代码

#include<cstdio> #include<iostream> #define ll long long #define INF 0x3f3f3f3f3f3f3f3f using namespace std; const int N = 3e5 + 100; int n, m, a[N]; int sta[N], id[N], tot; ll f[N]; struct XD_tree { ll f[N << 2]; void up(int now) { f[now] = min(f[now << 1], f[now << 1 | 1]); } void build(int now, int l, int r) { if (l == r) { if (l == 0) f[now] = 0; else f[now] = INF; return ; } int mid = (l + r) >> 1; build(now << 1, l, mid); build(now << 1 | 1, mid + 1, r); up(now); } ll query(int now, int l, int r, int L, int R) { if (L <= l && r <= R) return f[now]; int mid = (l + r) >> 1; ll re = INF; if (L <= mid) re = min(re, query(now << 1, l, mid, L, R)); if (mid < R) re = min(re, query(now << 1 | 1, mid + 1, r, L, R)); return re; } void update(int now, int l, int r, int pl, ll x) { if (l == r) { f[now] = x; return ; } int mid = (l + r) >> 1; if (pl <= mid) update(now << 1, l, mid, pl, x); else update(now << 1 | 1, mid + 1, r, pl, x); up(now); } void buildtmp(int now, int l, int r) { if (l == r) { f[now] = -a[l]; return ; } int mid = (l + r) >> 1; buildtmp(now << 1, l, mid); buildtmp(now << 1 | 1, mid + 1, r); up(now); } }T, tmp; int main() { freopen("hard.in", "r", stdin); freopen("hard.out", "w", stdout); scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); T.build(1, 0, n); tmp.buildtmp(1, 1, n); ll sum = 0; int l = 1; sta[0] = INF; for (int i = 1; i <= n; i++) { sum += a[i]; while (sum > m) { sum -= a[l]; l++; } while (sta[tot] < a[i]) { T.update(1, 0, n, id[tot - 1], INF); tot--; } T.update(1, 0, n, l - 1, f[l - 1] + -tmp.query(1, 1, n, l, i)); sta[++tot] = a[i]; id[tot] = i; T.update(1, 0, n, id[tot - 1], f[id[tot - 1]] + a[id[tot]]); f[i] = T.query(1, 0, n, l - 1, n - 1); } printf("%lld", f[n]); return 0; }

__EOF__

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