社区讨论
求解?!?
P3648[APIO2014] 序列分割参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mi86bzmb
- 此快照首次捕获于
- 2025/11/21 09:20 4 个月前
- 此快照最后确认于
- 2025/11/21 09:20 4 个月前
!?蜜汁优化?!
大夫,还能救一下吗?
C#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10, M = 210;
int n, k, ans;
int q[N], head = 1, tail = 1;
int a[N], sum[N], st;
int f[N][M], pre[N][M];
int Y(int i, int j, int m) {
return sum[j] * sum[n] - f[j][m - 1] - sum[i] * sum[n] + sum[i] * sum[i];
}
int X(int a) {
return sum[a];
}
int main() {
freopen("125.txt", "r", stdin);
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
sum[i] = sum[i - 1] + a[i];
}
for (int m = 1; m <= k; m++) {
head = 1, tail = 1;
for (int i = 1; i <= n; i++) {
while (head < tail && (Y(i, q[head + 1], m) - Y(i, q[head], m))
<= sum[i] * (X(q[head + 1]) - X(q[head])))head++;
int j = q[head];
f[i][m] = f[j][m - 1] + (sum[i] - sum[j]) * (sum[n] - sum[i]);
pre[i][m] = q[head];
if (ans < f[i][m]) {
ans = f[i][m];
st = i;
}
while (head < tail && (Y(i, q[tail], m) - Y(i, q[tail - 1], m)) * (X(i) - X(q[tail - 1]))
>= (Y(i, i, m) - Y(i, q[tail - 1], m)) * X(q[tail]) - X(q[tail - 1]))tail--;
q[++tail] = i;
}
}
printf("%d\n", ans);
for (int x = st, i = k; i >= 1; --i) x = pre[x][i], printf("%d ", x);
}
// f[i][m]=f[j][m-1]+(sum[i]-sum[j])*(sum[n]-sum[i]) 状态转移方程
// sum[i]*sum[i]+sum[j]*sum[n]-f[j][m-1] -sum[i]*sum[n]=sum[i]*sum[j]-f[i][m]; 优化方程
回复
共 2 条回复,欢迎继续交流。
正在加载回复...