第 153 场双周赛——将数组分割为子数组的最小代价
题目
题解
我们如果将此题暴力时间复杂度为O(n3),n的范围为1000是不行的,所以要降复杂度。我们可以把式子进行变化。
假如数组被划分成了三段A,B,C,那i⋅(s[r+1]−s[l])就变成了A,2B,3C
A + 2B + 3C = (A + B + C) + (B + C) + C
那我们就变成了求cost的后缀和,此时i就被消掉了,那时间复杂度就变成了O(n2)。然后再用划分型DP求解。定义 f[i+1] 表示下标 [0,i] 分割后的最小总代价。
这道题的难点就在于如何对这个式子进行变形。
参考代码
class Solution {
public:
long long minimumCost(vector<int>& nums, vector<int>& cost, int k) {
int n = nums.size();
vector<int> sn(n + 1, 0), sc(n + 1, 0);
for(int i = 0; i < n; i++) {
sn[i + 1] = sn[i] + nums[i];
sc[i + 1] = sc[i] + cost[i];
}
vector<long long> f(n + 1, LLONG_MAX);
f[0] = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i; j++) {
f[i] = min(f[i], f[j - 1] + 1LL * sn[i] * (sc[i] - sc[j - 1]) + k * (sc[n] - sc[j - 1]));
}
}
return f[n];
}
};

浙公网安备 33010602011771号