📅  最后修改于: 2023-12-03 14:55:40.499000             🧑  作者: Mango
给定一个整数对数组 nums ,其中nums[i] = [a[i], b[i]] ,要求从中选取若干个整数,并使这些整数满足以下条件:
输出满足条件的整数对中,整数之和的最大值。
输入:nums = [[3,4],[2,3],[1,2]] 输出:6 解释:选取 [1,2] 和 [3,4]。选取 [2,3] 会违反第二个限制条件。
输入:nums = [[1,3],[2,4],[3,6]] 输出:10 解释:选取 [1,3] 和 [3,6]。
本题涉及到贪心算法和动态规划算法。
首先将给定的整数对数组按照 a[i] + b[i] 从小到大排序。
根据题目中的第一个限制条件,可以得到以下贪心策略:每次选取 a[i] + b[i] 最小的整数对中的较大值。
这是因为,如果选取了某个整数对的较小值,那么就不能再选取与之匹配的整数对中的较大值,这将导致可能出现不可选取较大值的情况,从而降低整数之和的最大值。
但是,直接按照以上贪心策略选取整数对可能不满足第二个限制条件。对此,需要运用动态规划算法,设计一个状态转移方程,来检验当前选定的整数对是否符合第二个限制条件。
具体来说,设 dp[i][0] 表示只选取前 i 个整数对,不选取第 i 个整数对时的最大整数之和;dp[i][1] 表示只选取前 i 个整数对,选取第 i 个整数对时的最大整数之和。则状态转移方程如下:
最终的解即为 max(dp[n][0], dp[n][1]),其中 n 为整数对数组的长度。
def maxSum(nums: List[List[int]]) -> int:
n = len(nums)
nums.sort(key=lambda x: x[0] + x[1])
dp = [[0,0] for _ in range(n+1)]
for i in range(1, n+1):
j = i - 1
while j > 0 and nums[j-1][0] + nums[j-1][1] <= nums[i-1][0]:
j -= 1
dp[i][0] = max(dp[i-1][0], dp[i-1][1])
if j > 0:
dp[i][1] = max(dp[j][0], dp[j][1]) + nums[i-1][0]
return max(dp[n][0], dp[n][1])
以上代码的时间复杂度为 $O(n^2)$,空间复杂度为 $O(n)$。可以根据具体场景进行优化,例如使用滚动数组减小空间复杂度,或者使用二分查找来寻找最后一个符合第二个限制条件的整数对。