P2418 yyy loves OI IV
P2418 yyy loves OI IV
有两种转移情况,一种是差值在范围内用线段树查找转移,一种是同段连续的作为一段来转移。
注意旧的一段已经结束了新的一段要+1
#include<bits/stdc++.h> using namespace std; #define pii pair<int, int> #define mkp make_pair #define pb push_back #define ls(x) (x << 1) #define rs(x) ((x << 1) + 1) const int N = 1e6+10, inf = 1e9 + 7; int n, m, q, a[N], pre[N], dp[N], mn[N*4], p[N]; void upd(int x, int l, int r, int q, int k) { if (l == r) {mn[x] = min(mn[x], k); return;} int mid = (l + r) / 2; if (mid >= q) upd (ls(x), l, mid, q, k); else upd(rs(x), mid + 1, r, q, k); mn[x] = min(mn[ls(x)], mn[rs(x)]); } int que(int x, int l, int r, int ql, int qr) { if (l >= ql && r <= qr) return mn[x]; int mid = (l + r) / 2, res = inf; if (mid >= ql) res = min(res, que(ls(x), l, mid, ql, qr)); if (mid < qr) res = min(res, que(rs(x), mid + 1, r, ql, qr)); return res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; pre[0] = n + 1; int mxn = n*2 + 1; for (int i = 1; i <= n * 8 + 4; i++) mn[i] = inf; for (int i = 1; i <= n; i++) cin >> a[i], pre[i] = pre[i - 1] + ((a[i] == 1) ? 1 : (-1)); for (int i = 1; i <= n; i++) dp[i] = inf; dp[0] = 0; upd (1, 1, mxn, pre[0], 0); int lst = 0, preans = 0; for (int i = 1; i <= n; i++) { //对于连续一段来说只能由合法答案或是同段最小值转移 if (lst != a[i]) lst = a[i], preans = dp[i - 1]; int ql = max(1, pre[i] - m), qr = min(mxn, pre[i] + m); dp[i] = min(preans, que(1, 1, mxn, ql, qr)) + 1; upd (1, 1, mxn, pre[i], dp[i]); preans = min (preans, dp[i]); } cout << dp[n] << endl; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话