http://uoj.ac/problem/104

此题的重点是答案只与切割的最终形态有关,与切割顺序无关。

设\(f(i,j)\)表示前\(i\)个元素切成\(j\)个能产生的最大贡献。

\(f(i,j)=\max\{f(k,j-1)+sum(k+1,i)(sum(1,n)-sum(k+1,i)),k<i\}\),其中\(sum(l,r)=\sum\limits_{i=l}^ra_i,sum_k=\sum\limits_{i=1}^ka_i\)

有决策点\(k\)和\(l\),当\(k<l\)且\(l\)比\(k\)更优时,化出斜率优化dp的式子:$$-2sum_i<\frac{\left(f(l,j-1)-sum_nsum_l-sum_l2\right)-\left(f(k,j-1)-sum_nsum_k-sum_k2\right)}{sum_l-sum_k}$$

可以把每个决策点\(k\)看成横坐标为\(sum_k\),纵坐标为\(f(l,j-1)-sum_nsum_l-sum_l^2\)的点,每次用斜率为\(-2sum_i\)的直线平移到这个点上,找纵截距最大的直线经过的点作为决策点。

决策点一定在上凸壳,因为\(sum_i\)单调不降,用单调栈维护上凸壳即可。

又因为\(-2sum_i\)单调不升,具有决策单调性,把单调栈改成双端队列,每次不断从队首弹出不够优的决策点。

时间复杂度\(O(nk)\)。

为什么uoj上的样例本机AC提交RE???删掉inline还T???卡常数!手动把函数压倒主函数里,快速读入,还有二维数组把较小的一维放在前面,这个优化效果最明显!

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll; int in() {
char c = getchar(); int k = 0;
for (; c < '0' || c > '9'; c = getchar());
for (; c >= '0' && c <= '9'; c = getchar())
k = k * 10 + (c ^ 48);
return k;
} const int N = 100003;
const int K = 203; int n, k, pre[K][N], a[N], head, tail, qu[N];
ll f[K][N], S, sum[N], qucal[N]; ll calzj;
int cut[N], cuttot = 0; int main() {
n = in(); k = in();
for (int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + (a[i] = in());
S = sum[n]; for (int i = 1; i <= n; ++i)
f[1][i] = 1ll * sum[i] * (S - sum[i]); for (int j = 2; j <= k + 1; ++j) {
head = 0; tail = 0; qu[0] = 0;
for (int i = 1; i <= n; ++i) {
while (head < tail && qucal[head + 1] - qucal[head] >= (sum[qu[head + 1]] - sum[qu[head]]) * (sum[i] * -2)) ++head;
ll sumlr = sum[i] - sum[qu[head]];
f[j][i] = f[j - 1][qu[head]] + sumlr * (S - sumlr);
pre[j][i] = qu[head];
calzj = f[j - 1][i] - S * sum[i] - sum[i] * sum[i];
while (head < tail && (sum[qu[tail]] == sum[i] ? (calzj >= qucal[tail]) : (calzj - qucal[tail]) * (sum[qu[tail]] - sum[qu[tail - 1]]) > (qucal[tail] - qucal[tail - 1]) * (sum[i] - sum[qu[tail]]))) --tail;
if (sum[qu[tail]] != sum[i]) qu[++tail] = i, qucal[tail] = calzj;
else if (head == tail && calzj >= qucal[head]) qu[tail] = i, qucal[tail] = calzj;
}
} printf("%lld\n", f[k + 1][n] >> 1);
int tmp = n;
for (int i = k + 1; i > 1; --i)
tmp = cut[++cuttot] = pre[i][tmp];
for (int i = cuttot; i >= 1; --i) printf("%d ", cut[i]); return 0;
}

【UOJ #104】【APIO 2014】Split the sequence的更多相关文章

  1. 【UOJ #103】【APIO 2014】Palindromes

    http://uoj.ac/problem/103 由manacher得:本质不同的回文串只有\(O(n)\)个. 用manacher求出所有本质不同的回文串,对每个本质不同的回文串,在后缀自动机的p ...

  2. uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题

    [清华集训2014]矩阵变换 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/41 Description 给出 ...

  3. AC日记——【清华集训2014】奇数国 uoj 38

    #38. [清华集训2014]奇数国 思路: 题目中的number与product不想冲: 即为number与product互素: 所以,求phi(product)即可: 除一个数等同于在模的意义下乘 ...

  4. 【UOJ】67 新年的毒瘤 &【BZOJ】1123 BLO

    [UOJ 67] 题目链接: 传送门 题解: 第一眼很懵逼……这什么鬼. 思考什么点复合条件……(o(>﹏<)o 1.树,也就是说还剩n-2条边,等价于要删去一个度数为m-n+2的点. 2 ...

  5. 【UOJ#236】[IOI2016]railroad(欧拉回路,最小生成树)

    [UOJ#236][IOI2016]railroad(欧拉回路,最小生成树) 题面 UOJ 题解 把速度看成点,给定的路段看成边,那么现在就有了若干边,然后现在要补上若干边,以及一条\([inf,\) ...

  6. 【UOJ#177】欧拉回路

    [UOJ#177]欧拉回路 题面 UOJ 题解 首先图不连通就没啥好搞的了. 对于无向图而言,每个点度数为偶数. 对于有向图而言,每个点入度等于出度. 然后就是一本通上有的做法,直接\(dfs\)一遍 ...

  7. 【UOJ#311】【UNR #2】积劳成疾(动态规划)

    [UOJ#311][UNR #2]积劳成疾(动态规划) UOJ Solution 考虑最大值分治解决问题.每次枚举最大值所在的位置,强制不能跨过最大值,左右此时不会影响,可以分开考虑. 那么设\(f[ ...

  8. 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)

    [UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...

  9. 【UOJ#246】套路(动态规划)

    [UOJ#246]套路(动态规划) 题面 UOJ 题解 假如答案的选择的区间长度很小,我们可以做一个暴力\(dp\)计算\(s(l,r)\),即\(s(l,r)=min(s(l+1,r),s(l,r- ...

随机推荐

  1. Date对象相关函数使用

    参考:http://www.w3school.com.cn/jsref/jsref_obj_date.asp

  2. SVM支持向量机的基本原理

    SVM支持向量机的基本原理 对于很多分类问题,例如最简单的,一个平面上的两类不同的点,如何将它用一条直线分开?在平面上我们可能无法实现,但是如果通过某种映射,将这些点映射到其它空间(比如说球面上等), ...

  3. python基础之上下文管理器

    前言 关于计算器运行的上下文的概念,我的理解也不是很深:按我的理解就是程序在运行之前,其所需要的资源,运行环境等都会被序列化,然后加入到CPU的任务队列中,等待调度系统分配时间片执行.下面谈谈pyth ...

  4. windows和linux修改python的pip源

    python的pip安装包非常方便,然而其默认的镜像源在国外,下载的速度非常慢,推荐改成国内的镜像源. window平台修改pip源 找到系统盘下C:\C:\Users\用户名\AppData\Roa ...

  5. django框架<二>

    django框架:   Models 1.基本创建 Django提供了一个抽象层("Model")的构建和管理Web应用程序的数据. Django使用一种新的方式,即:关系对象映射 ...

  6. APP版本号记录

    VoLTE版本: VT_BV0800V1.0.0B06 800M版本: NETARTIST_BV0800V1.0.0B01 看详细版本号:9831275#

  7. Docker Commands

    Docker Commands 安装,以Ubuntu 14.04.3为例 apt-get install docker.io 注意安装之前需要更新系统 列出曾经存在的容器 docker ps -a 列 ...

  8. C++学习笔记--从虚函数说开去

    虚函数与纯虚函数: 虚函数:在某基类中声明为virtual并在一个或多个派生类中被重新定义的成员函数,virtual  函数返回类型  函数名(参数表){函数体;} ,实现多态性,通过指向派生类的基类 ...

  9. java基础9 main函数、this、static、super、final、instanceof 关键字

    一.main函数详解 1.public:公共的.权限是最大的,在任何情况都可以访问  原因:为了保证jvm在任何情况下都可以访问到main法2.static:静态,静态可以让jvm调用更方便,不需要用 ...

  10. xss 过滤

    一. xss过滤 用户通过Form获取展示在终端, 提交数据,Form验证里面加入xss验证(对用户提交的内容验证是否有关键标签) from django.conf.urls import url f ...