题目:
给你一个整数数组 nums
和一个 非负 整数 k
。如果一个整数序列 seq
满足在范围下标范围 [0, seq.length - 2]
中存在 不超过 k
个下标 i
满足 seq[i] != seq[i + 1]
,那么我们称这个整数序列为 好 序列。请你返回 nums
中 好 子序列的最长长度
示例 1:
输入:nums = [1,2,1,1,3], k = 2
输出:4
解释:
最长好子序列为 [1,2,1,1,3]
。
示例 2:
输入:nums = [1,2,3,4,5,1], k = 0
输出:2
解释:
最长好子序列为 [1,2,3,4,5,1]
。
提示:
1 <= nums.length <= 500
1 <= nums[i] <= 109
0 <= k <= min(nums.length, 25)
思路:
很容易想到用 dp[i][j] 来表示以 nums[i] 结尾组成的最长合法序列中有 j 个数字与其在序列中的后一个数字不相等。其中 i 的取值为 nums 的长度,j 不超过 k。初始时,有 dp[i][0] = 1。对于转移,可以枚举每一个满足 x<i 的下标,有:
dp[i][j] = max j dp[x][j − (nums[x] != nums[i])] + 1
代码:
class Solution {
public:
int maximumLength(vector<int>& nums, int k) {
int ans = 0;
int len = nums.size();
vector<vector<int>> dp;
dp.resize(len, vector<int>(51, -1));
for (int i = 0; i < len; i++) {
dp[i][0] = 1;
for (int l = 0; l <= k; l++) {
for (int j = 0; j < i; j++) {
int add = (nums[i] != nums[j]);
if (l - add >= 0 && dp[j][l - add] != -1) {
dp[i][l] = max(dp[i][l], dp[j][l - add] + 1);
}
}
ans = max(ans, dp[i][l]);
}
}
return ans;
}
};