#2122. 最长非连续子序列和为给定值
最长非连续子序列和为给定值
🎯 最长非连续子序列和为给定值(Longest Subsequence with Sum K)
📘 题目描述
给定一个长度为 n 的整数数组 a[1..n],以及一个目标整数 K,请你找出一个最长的非连续子序列,使得该子序列的和恰好等于 K。
注意:
- 子序列中的元素顺序不变;
- 子序列中的元素可以跳过中间项,不要求连续;
- 若不存在这样的子序列,输出
0。
📥 输入格式
- 第一行两个整数:
n和K。 - 第二行
n个整数:数组a[1..n]。
📤 输出格式
- 一个整数,表示和为
K的最长非连续子序列的长度。如果无法满足,则输出 0。
💡 输入输出样例
输入样例 #1
5 15
2 3 7 8 10
输出样例 #1
3
解释:最长子序列 [2, 3, 10],总和为 15,长度为 3。
输入样例 #2
5 9
1 2 3 4 5
输出样例 #2
3
解释:最长子序列 [1, 3, 5]。
🚧 边界样例
| 输入 | 输出 |
|---|---|
1 1[1] |
1 |
1 2[1] |
0 |
3 3[1, 1, 1] |
3 |
4 10[10, 1, 1, 1] |
1 |
🧠 解题思路(动态规划)
我们定义一个二维 dp[i][s] 表示:
- 用前
i个数能否凑出和为s的子序列; - 值为
-1表示无法凑出; - 否则存储能凑出该和的最长子序列的长度。
⚙ 状态转移方程
dp[i][s] = max(
dp[i-1][s], // 不选 a[i]
dp[i-1][s - a[i]] + 1 // 选 a[i]
)
- 初始状态:
dp[0][0] = 0(选 0 个数凑出和为 0); - 答案是
dp[n][K]; - 注意空间和时间都为
O(n × K),需要用memset或 vector 初始化。