CSP-S 2019 划分

Posted hock

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSP-S 2019 划分相关的知识,希望对你有一定的参考价值。

( ext {划分})

将一个序列分为(m)((m)自己决定())并且每一段的和递增 求(sum_{i=0}^m s_i ^ 2)

(s_i)为每一段的和

subtask1 ( ext {期望得分 36pts})

比较好想 (f[i][j])表示最后一段尾部端点尾(i) 头端点为(j) 的最小代价
[f[i][j] = max(f[j][k] + sqr((s[i] - s[j])))]

subtask2 ( ext {期望得分 64pts})

可以优化一下枚举(i,j)然后二分找到(k) 时间复杂度(O(n^2 log n))

subtask3 ( ext {期望得分 64pts})

可以证明如果一个区间大于前面的区间 且可以分为 ( ext {a b (pre <= a <= b}))

那么将他分开一定是最优的 那么对于一个(i) 我们去维护一个(f[i])并且使得(s[i] - s[f[i]])最小化 答案一定是最优的

我们可以((n^2))找到一个最优的(f[i])然后就得到了(64pts)的高分

std ( ext {期望得分 100pts})

暴力(O(n ^ 2))未免太暴力了 我们可以想满足条件 (s[i] - s[j] >= s[j] - s[f[j]])

移项可得(s[i] >= s[j] * 2 - s[f[j]]) 我们只需找到最后一个满足这个条件的值

然后(f[i] = j)就行了 这个东西可以用单调队列去写

int head = 1, tail = 1; 
for (int i = 1; i <= n; i ++ ) { 
    while (head < tail && calc (q[head + 1]) <= s[i]) head ++ ; 
    g[i] = q[head]; 
    while (head < tail && calc (q[tail]) >= calc (i)) tail -- ;     
    q[++tail] = i; 
} 
for (int i = n; i >= 1; i = g[i]) ans = (ans + sqr (s[i] - s[g[i]]));

分析

(36)比较( ext{navie})难度普及

(64) 分析性质 难度提高

(100) 用单调队列维护不难想 关键是前面一步的证明 难度提高+

以上是关于CSP-S 2019 划分的主要内容,如果未能解决你的问题,请参考以下文章

CSP-S2019-day2

CSP-S2019题解

[csp-s]2019游记

2019.10.26 csp-s模拟测试88 反思总结

「CSP-S模拟赛」2019第二场

[常见做法整合]CSP-S2019 D2T3 树的重心