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. 【BZOJ4870】组合数问题(计数DP,快速幂)

    题意: 1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1 思路:From http://blog.csdn.net/qq_33229466/artic ...

  2. 【CodeForces】899 E. Segments Removal

    [题目]E. Segments Removal [题意]给定n个数字,每次操作删除最长的连续相同数字(等长删最左),求全部删完的最少次数.n<=2*10^6,1<=ai<=10^9. ...

  3. js、php本周第一天和本周最后一天

    PHP:本周一 echo date('Y-m-d',(time()-((date('w')==0?7:date('w'))-1)*24*3600)); //w为星期几的数字形式,这里0为周日 本周日 ...

  4. 2017ACM暑期多校联合训练 - Team 8 1006 HDU 6138 Fleet of the Eternal Throne (字符串处理 AC自动机)

    题目链接 Problem Description The Eternal Fleet was built many centuries ago before the time of Valkorion ...

  5. koa通过get请求获取参数

    1.通过get方式请求获取参数的方式有两种 通过上下文获取 通过request获取 获得的格式有两种:query与querystring 注意:querystring为小写,驼峰格式会导致无法获取 2 ...

  6. powerpc平台移植zebra或quagga-0.99.23

    1,先configure  ./configure   --enable-vtysh --disable-bgpd --disable-ripd --disable-ripngd --disable- ...

  7. sql server 2008 r2 产品密钥

    数据中心版:PTTFM-X467G-P7RH2-3Q6CG-4DMYBDDT3B-8W62X-P9JD6-8MX7M-HWK38==================================== ...

  8. Feign 发送对象,对象含多个文件

    Feign在发送文件时,可以使用Feign-form. 另一种方式,关键就是,要将文件转成Resource,然后使用Spring的MultivalueMap 本次发送的是个对象,对象里含有 文件对象数 ...

  9. mysql 配置数据库主从同步

    参考:https://www.cnblogs.com/kevingrace/p/6256603.html http://www.51testing.com/html/00/130600-243651. ...

  10. URL中斜杠/和反斜杠\的区别小结

    Unix使用斜杆/ 作为路径分隔符,而web应用最新使用在Unix系统上面,所以目前所有的网络地址都采用 斜杆/ 作为分隔符. Windows由于使用 斜杆/ 作为DOS命令提示符的参数标志了,为了不 ...