CF 1527 E
题目描述
我们定义一个数组
这里
你需要将数组
思路
令
由于代价是最后一个减前一个,可以看作是
所以转移可以这样来实现:当枚举到
每次做完一轮 dp 就把
空间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 35005;
struct Segment_Tree {
int l[MAXN << 2], r[MAXN << 2], Min[MAXN << 2], lazy[MAXN << 2];
void build(int u, int s, int t) {
l[u] = s, r[u] = t, lazy[u] = 0;
if(s == t) {
Min[u] = 0;
return;
}
int mid = (s + t) >> 1;
build(u << 1, s, mid), build((u << 1) | 1, mid + 1, t);
Min[u] = min(Min[u << 1], Min[(u << 1) | 1]);
}
void tag(int u, int x) {
Min[u] += x, lazy[u] += x;
}
void pushdown(int u) {
tag(u << 1, lazy[u]), tag((u << 1) | 1, lazy[u]), lazy[u] = 0;
}
void update(int u, int s, int t, int x) {
if(s > t) {
return;
}
if(l[u] >= s && r[u] <= t) {
tag(u, x);
return;
}
pushdown(u);
if(s <= r[u << 1]) {
update(u << 1, s, t, x);
}
if(t >= l[(u << 1) | 1]) {
update((u << 1) | 1, s, t, x);
}
Min[u] = min(Min[u << 1], Min[(u << 1) | 1]);
}
int Getmin(int u, int s, int t) {
if(s > t) {
return 0;
}
if(l[u] >= s && r[u] <= t) {
return Min[u];
}
pushdown(u);
int x = int(2e9);
if(s <= r[u << 1]) {
x = min(x, Getmin(u << 1, s, t));
}
if(t >= l[(u << 1) | 1]) {
x = min(x, Getmin((u << 1) | 1, s, t));
}
return x;
}
}tr;
int n, k, a[MAXN], last[MAXN], dp[MAXN];
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> k;
for(int i = 2; i <= n + 1; ++i) {
cin >> a[i];
}
tr.build(1, 1, n + 1);
tr.update(1, 2, n + 1, int(2e9));
for(int i = 1; i <= k; ++i) {
for(int j = 1; j <= n; ++j) {
last[j] = 1;
}
for(int j = 2; j <= n + 1; ++j) {
tr.update(1, 1, last[a[j]] - 1, j - last[a[j]]);
last[a[j]] = j;
dp[j] = tr.Getmin(1, 1, j - 1);
}
tr.build(1, 1, n + 1);
tr.update(1, 1, 1, int(2e9));
for(int j = 2; j <= n + 1; ++j) {
tr.update(1, j, j, dp[j]);
}
}
cout << dp[n + 1];
return 0;
}
本文作者:Yaosicheng124
本文链接:https://www.cnblogs.com/yaosicheng124/p/18417386
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步