第 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];
    }
};
posted @ 2025-04-02 23:00  PZnwbh  阅读(16)  评论(0)    收藏  举报