题意
题解
d p [ i ] [ j ] dp[i][j] dp[i][j] 代表终点为第 i i i 个数组的 j j j 个位置可获得的最大分数,设相同数字在另一个数组对应的索引为 i d x idx idx
d p [ i ] [ j ] = { d p [ i ] [ j − 1 ] + n u m s [ i ] [ j ] d p [ i ⊕ 1 ] [ i d x − 1 ] + n u m s [ i ] [ j ] dp[i][j]=\begin{cases} dp[i][j-1]+nums[i][j] \\ dp[i\oplus1][idx-1]+nums[i][j]\\ \end{cases} dp[i][j]={dp[i][j−1]+nums[i][j]dp[i⊕1][idx−1]+nums[i][j]
m a p map map 记录元素的索引值,记忆化搜索求解即可。
class Solution
{
#define mod 1000000007
#define maxn 100005
typedef long long ll;
public:
ll dp[2][maxn];
unordered_map<int, vector<int>> mp;
ll rec(int i, int j, vector<int> &nums1, vector<int> &nums2)
{
if (j < 0)
return 0;
if (dp[i][j] != -1)
return dp[i][j];
vector<int> &x = (i ? nums2 : nums1);
ll res = rec(i, j - 1, nums1, nums2) + x[j];
if (mp[x[j]].size() == 2)
{
int pre = (i ^ 1) & 1;
res = max(res, rec(pre, mp[x[j]][pre] - 1, nums1, nums2) + x[j]);
}
return dp[i][j] = res;
}
int maxSum(vector<int> &nums1, vector<int> &nums2)
{
int n1 = nums1.size(), n2 = nums2.size();
for (int i = 0; i < n1; i++)
{
mp[nums1[i]].push_back(i);
}
for (int i = 0; i < n2; i++)
{
mp[nums2[i]].push_back(i);
}
memset(dp, -1, sizeof(dp));
return max(rec(0, n1 - 1, nums1, nums2), rec(1, n2 - 1, nums1, nums2)) % mod;
}
};