3500:将数组分割为子数组的最小代价(2569 分)
目录
题目
给你两个长度相等的整数数组 nums
和 cost
,和一个整数 k
。
你可以将 nums
分割成多个子数组。第 i
个子数组由元素 nums[l..r]
组成,其代价为:
(nums[0] + nums[1] + ... + nums[r] + k * i) * (cost[l] + cost[l + 1] + ... + cost[r])
。
注意,i
表示子数组的顺序:第一个子数组为 1,第二个为 2,依此类推。
返回通过任何有效划分得到的 最小 总代价。
子数组 是一个连续的 非空 元素序列。
示例 1:
输入: nums = [3,1,4], cost = [4,6,6], k = 1
输出: 110
解释:
将nums
分割为子数组 [3, 1]
和 [4]
,得到最小总代价。
- 第一个子数组
[3,1]
的代价是(3 + 1 + 1 * 1) * (4 + 6) = 50
。 - 第二个子数组
[4]
的代价是(3 + 1 + 4 + 1 * 2) * 6 = 60
。
示例 2:
输入: nums = [4,8,5,1,14,2,2,12,1], cost = [7,2,8,4,2,2,1,1,2], k = 7
输出: 985
解释:
将nums
分割为子数组 [4, 8, 5, 1]
,[14, 2, 2]
和 [12, 1]
,得到最小总代价。
- 第一个子数组
[4, 8, 5, 1]
的代价是(4 + 8 + 5 + 1 + 7 * 1) * (7 + 2 + 8 + 4) = 525
。 - 第二个子数组
[14, 2, 2]
的代价是(4 + 8 + 5 + 1 + 14 + 2 + 2 + 7 * 2) * (2 + 2 + 1) = 250
。 - 第三个子数组
[12, 1]
的代价是(4 + 8 + 5 + 1 + 14 + 2 + 2 + 12 + 1 + 7 * 3) * (1 + 2) = 210
。
提示:
1 <= nums.length <= 1000
cost.length == nums.length
1 <= nums[i], cost[i] <= 1000
1 <= k <= 1000
相似问题:
分析
#1
- 令 p1 为 nums 的前缀和数组,p2 为 cost 的前缀和数组
- 第 i 个子数组 nums[l:r] 的代价即为 (p1[r]+ki)(p2[r]-p2[l])=p1[r](p2[r]-p2[l])+ki*(p2[r]-p2[l])
- i*(p2[r]-p2[l]) 有个经典的变形是将其替换为 p2[n]-p2[l],最后总的代价是一样的
- 第 i 个子数组 nums[l:r] 的代价转为 p1[r](p2[r]-p2[l])+k(p2[-1]-p2[l])
- 用划分 dp 即可解决
|
|
3126 ms
#2
- 将递推式改写为 f[i]=p1[i]p2[i]+kp2[-1]-min((p1[i]+k)*p2[j]-f[j])
- (p1[i]+k)*p2[j]-f[j] 是典型的可以斜率优化的式子
- 由于 p1[i]+k 单调递增,可以直接边递推边维护凸包
解答
|
|
131 ms