大型补档计划

题目链接

若 \(K = 1\),显然,\(B[i]\) 取 \(A\) 序列的中位数时最优。

考虑扩展,我们只需要把 \(A\) 分成 \(K\) 段,每段内, \(B\) 最优的取值即这一段的中位数

设 \(g(l, r)\) 为 \([l, r]\) 这一段 A 数组序列的中位数

设 \(f[i][j]\) 为把前 \(i\) 个数分成 \(j\) 段的最小值。

考虑枚举一个 \(k < i\)

\(f[i][j] = min(f[k][j - 1] + g(k + 1, i))\)

若朴素计算 g,则复杂度 O(N ^ 3K)

从大往小枚举 k。

我们需要一个数据结构支持两个操作:

  • 加入一个数 a[k + 1]

  • 查询集合中所有数与中位数差的绝对值。

这就是动态中位数那道题,可以用对顶堆 / 线段树 / 平衡树,由于对顶堆比较好写就用它了。

然后复杂度就是 \(O(N ^ 2KLogN)\)。但是复杂度还是 \(1e9\) 左右,会暴毙。

考虑 \(g(k + 1, i)\) 不随 j 的变化而变化,所以可以预处理 \(g(k + 1, i)\) (时间复杂度\(O(N^2LogN)\))

复杂度就是\(O(N ^ 2K) 1e8\) 跑的还是很慌 #只有吸氧才能过哇哇哇

#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
#define rint register int
using namespace std;
const int N = 2005, S = 26; int n, K, a[N], s1, s2, f[N][S], g[N][N];
priority_queue<int> q1; // 大跟堆
priority_queue<int, vector<int>, greater<int> > q2; // 小跟堆 void inline clear() {
while (q1.size()) q1.pop();
while (q2.size()) q2.pop();
s1 = s2 = 0; }
void inline insert(int x) {
if (q1.empty() || x <= q1.top()) q1.push(x), s1 += x;
else q2.push(x), s2 += x;
// 保持 q1.size == q2.size 或者 q1.size == q2.size + 1
if (q1.size() > q2.size() + 1) {
s2 += q1.top(), s1 -= q1.top();
q2.push(q1.top()), q1.pop();
} else if (q2.size() > q1.size()) {
s1 += q2.top(), s2 -= q2.top();
q1.push(q2.top()), q2.pop();
}
}
int inline query() {
int s = 0;
if (q1.size()) s += q1.top() * q1.size() - s1;
if (q2.size()) s += s2 - q1.top() * q2.size();
return s;
}
int main() {
while (scanf("%d%d", &n, &K), n || K) {
memset(f, 0x3f, sizeof f);
for (rint i = 1; i <= n; i++) scanf("%d", a + i);
for (rint i = 1; i <= n; i++) {
clear();
for (int k = i; k; k--)
insert(a[k]), g[k][i] = query();
}
f[0][0] = 0;
for (rint i = 1; i <= n; i++) {
for (rint j = 1; j <= K; j++)
for (rint k = 0; k < i; k++)
f[i][j] = min(f[i][j], f[k][j - 1] + g[k + 1][i]);
}
printf("%d\n", f[n][K]);
}
return 0;
}

最新文章

  1. WindowsForm菜单工具栏--2016年12月6日
  2. Github两步认证
  3. 2015年第7本(英文第6本):纳尼亚传奇I–狮子、女巫、魔衣橱
  4. 【读书笔记】iOS-开发技巧-UILabel内容模糊的原因
  5. volatile关键字
  6. c# 控件闪烁处理方法
  7. ASP.NET和支付宝合作开发第三方接口的注意事项
  8. google yeoman
  9. 【原创】CLEVO P157SM外接鼠标键盘失灵解决:更换硅脂(附带最新跑分数据)
  10. 使用repeater开发出现 回发或回调参数无效 的问题
  11. 【DateStructure】 Charnming usages of Map collection in Java
  12. mojo 默认启用utf-8
  13. 最新Hadoop Shell完全讲解
  14. table常用的属性以及用法
  15. 白话大数据 | Spark和Hadoop到底谁更厉害?
  16. HttpWebRequest 改为 HttpClient 踩坑记-请求头设置
  17. openstack-HTTP exception thrown: Maximum number of ports exceeded错误解决方案
  18. less/sass 基础base文件
  19. js源生ajax
  20. django搭建一个小型的服务器运维网站-拿来即用的bootstrap模板

热门文章

  1. 基于FFmpeg的Dxva2硬解码及Direct3D显示(二)
  2. 剑指offer刷题(Tree)
  3. typora 图片存储在COS
  4. 五:key关键字 string字符串 list列表 set集合 Zset有序集合
  5. Git 分支相关
  6. 一个提高GPU模糊算法的速度的方法
  7. empty
  8. 这个厉害了,ssm框架整合全过程,建议收藏起来好好看看
  9. 面试官:小伙子,你给我说一下你对MySQL索引的理解吧
  10. Wasp XT合成器功能介绍