1 条题解
-
0
Cute Subsequences 详细中文题解
一、题目重述与核心概念解析
题目大意
给定长度为的正整数数组,和正整数,要求:
- 将数组划分成个非空子序列,每个元素恰好属于一个子序列;
- 对第个子序列(元素下标),定义它的值为:(是元素在子序列中的位置);
- 划分的总代价是所有子序列的值之和,求最大总代价。
关键定义澄清
- 子序列:保持原数组顺序,元素可拆分到不同子序列,不要求连续;
- 子序列的值:元素在子序列内的位置 + 元素本身的值,取这个和的最大值;
- 约束:,,要求算法。
二、公式转化与核心观察
第一步:位置公式变形
设原数组中第个元素()被分到某个子序列的第位,则这个元素对所在子序列的值的贡献为:
我们可以把子序列内的位置 转化为原数组的全局计数:
- 假设我们把数组分成个子序列,遍历原数组时,每个元素会被分配到其中一个子序列的末尾;
- 对于原数组第个元素,它在子序列中的位置 = 该元素被分配到的子序列,此前已经分配的元素个数 + 1。
第二步:核心结论
我们先计算所有元素的基础值:
这个值对应:把每个元素单独作为一个子序列时的总代价(此时每个元素的,值为)。
当我们需要合并子序列(从个合并到个,需要合并次)时,总代价只会减少,不会增加。 因此:最大化总代价 = 最小化合并带来的损失。
第三步:合并损失的计算
对于两个元素,如果把接在所在子序列的末尾:
- 的位置不变,贡献不变;
- 的位置从变成,它的贡献从变成吗?❌ 错误!
正确的贡献公式: 对原数组第个元素,定义:
这是本题的核心转化公式。
最终核心结论
- 答案的基础总和 = ;
- 我们需要选择个最大的,最终答案 = 这个最大的和。
三、证明
- 每个子序列的值,等价于该子序列中最大的();
- 总代价 = 所有子序列的最大值之和;
- 要让总和最大,只需选个最大的,让每个最大值分别作为一个子序列的最大值。
这是解决本题的唯一核心:计算所有,取前大的数求和。
四、样例验证
输入:
计算(下标从1开始):
数组: 取前3大的数: 求和:,与样例输出一致。
五、算法设计
步骤
- 遍历数组,计算每个位置的(代码中下标从0开始);
- 将数组降序排序;
- 取前个元素求和,输出结果。
复杂度分析
- 计算:
- 排序:
- 求和: 总复杂度,完美适配的约束。
七、总结
- 核心转化:将子序列内位置与原数组下标结合,得到;
- 本质:总代价等于个最大的和;
- 解法:计算→排序→取前大求和;
- 复杂度:,通过所有测试用例。
- 1
信息
- ID
- 6383
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者