題目:
給你一個整數數組 nums 和一個整數 k 。
將數組拆分成一些非空子數組。拆分的 代價 是每個子數組中的 重要性 之和。
令 trimmed(subarray) 作為子數組的一個特征,其中所有僅出現一次的數字將會被移除。
例如,trimmed([3,1,2,4,3,4]) = [3,4,3,4] 。
子數組的 重要性 定義為 k + trimmed(subarray).length 。
例如,如果一個子數組是 [1,2,3,3,3,4,4] ,trimmed([1,2,3,3,3,4,4]) = [3,3,3,4,4] 。這個子數組的重要性就是 k + 5 。
找出并返回拆分 nums 的所有可行方案中的最小代價。
子數組 是數組的一個連續 非空 元素序列。
示例 1:
輸入:nums = [1,2,1,2,1,3,3], k = 2
輸出:8
解釋:將 nums 拆分成兩個子數組:[1,2], [1,2,1,3,3]
[1,2] 的重要性是 2 + (0) = 2 。
[1,2,1,3,3] 的重要性是 2 + (2 + 2) = 6 。
拆分的代價是 2 + 6 = 8 ,可以證明這是所有可行的拆分方案中的最小代價。
示例 2:
輸入:nums = [1,2,1,2,1], k = 2
輸出:6
解釋:將 nums 拆分成兩個子數組:[1,2], [1,2,1] 。
[1,2] 的重要性是 2 + (0) = 2 。
[1,2,1] 的重要性是 2 + (2) = 4 。
拆分的代價是 2 + 4 = 6 ,可以證明這是所有可行的拆分方案中的最小代價。
示例 3:
輸入:nums = [1,2,1,2,1], k = 5
輸出:10
解釋:將 nums 拆分成一個子數組:[1,2,1,2,1].
[1,2,1,2,1] 的重要性是 5 + (3 + 2) = 10 。
拆分的代價是 10 ,可以證明這是所有可行的拆分方案中的最小代價。
提示:
1 <= nums.length <= 1000
0 <= nums[i] < nums.length
1 <= k <= 10^9
java代碼:
class Solution {public int minCost(int[] nums, int k) {int n = nums.length;int[] f = new int[n + 1];byte[] state = new byte[n];for (int i = 0; i < n; ++i) {Arrays.fill(state, (byte) 0);int unique = 0, mn = Integer.MAX_VALUE;for (int j = i; j >= 0; --j) {int x = nums[j];if (state[x] == 0) { // 首次出現state[x] = 1;++unique;} else if (state[x] == 1) { // 不再唯一state[x] = 2;--unique;}mn = Math.min(mn, f[j] - unique);}f[i + 1] = k + mn;}return f[n] + n;}
}