题目:
给你一个整数数组 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 <= 5001 <= nums[i] <= 1090 <= 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;
    }
};