设dp[i][j]
为nums1的前i位
和nums2的前j位
中取出的等长子序列的最大点积。
假设新加入nums1[i]和nums2[j]
至子序列,则:
dp[i][j] = dp[i-1][j-1] + nums1[i] * nums2[j](乘积可能为负)
假设不加入任何数,则:
dp[i][j] = max(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
发现转移方程仅与i-1
有关,可以节省空间
class Solution:
def maxDotProduct(self, nums1: List[int], nums2: List[int]) -> int:
INF = 1e9
len1 = len(nums1)
len2 = len(nums2)
ans = -INF
dp = [-INF for i in range(len2)]
for i in range(len1):
for j in range(1, len2):
if dp[j - 1] > dp[j]:
dp[j] = dp[j - 1]
#dp[i][j]=max(dp[i][j],dp[i-1][j-1]+add)
for j in range(len2 - 1, -1, -1):
#传统艺能,原数组上更新要反着来
add = nums1[i] * nums2[j]
#由于直接在原数组上更新,因此自带dp[i][j]=max(dp[i][j],dp[i-1][j])
if add > dp[j]:
dp[j] = add
#本应为dp[i][j]=max(0,dp[i][j],add),但题目要求非空
if (j > 0 and add + dp[j - 1] > dp[j]):
dp[j] = add + dp[j - 1]
#dp[i][j]=max(dp[i][j],dp[i-1][j-1]+add)
return max(dp)