考点
思路
题意是,数组最多划分k + 1个子数组,每个子数组的开销为:
\[
\text{cost}(i,j) = \max_{t\in[i,j]} nums[t]\cdot (j-i+1) - \sum_{t=i}^j
nums[t]
\] 求子数组开销和的最小值
之所以可以这么认为,是因为就算两个区间的最大值一样,按题意应该合并成一个区间的;
可不论合并与否,这两个数组转换为区间最大值的开销并没有改变,即不会对答案造成任何影响
AC代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public: int minSpaceWastedKResizing(vector<int>& nums, int k) { k++; int f[205][205], n = nums.size(); memset(f, 0x3f, sizeof(f)); f[0][0] = 0; for (int j = 1; j <= k; ++j) { for (int r = j; r <= n; ++r) { int mx = -1, s = 0; for (int l = r; l >= j; --l) { s += nums[l - 1]; mx = max(mx, nums[l - 1]); f[j][r] = min(f[j][r], f[j - 1][l - 1] + (r - l + 1) * mx - s); } } } return f[k][n]; } };
|
滚动数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public: const int inf = 0x3f3f3f3f; int minSpaceWastedKResizing(vector<int>& nums, int k) { k++; int f[2][205], n = nums.size(); memset(f, 0x3f, sizeof(f)); f[0][0] = 0; for (int j = 1; j <= k; ++j) { for (int r = j; r <= n; ++r) { int mx = -1, s = 0; f[j & 1][r] = inf; for (int l = r; l >= j; --l) { s += nums[l - 1], mx = max(mx, nums[l - 1]); f[j & 1][r] = min(f[j & 1][r], f[j - 1 & 1][l - 1] + (r - l + 1) * mx - s); } } } return f[k & 1][n]; } };
|