【动态规划-最长公共子序列(LCS)】【hard】力扣1458. 两个子序列的最大点积

给你两个数组 nums1 和 nums2 。

请你返回 nums1 和 nums2 中两个长度相同的 非空 子序列的最大点积。

数组的非空子序列是通过删除原数组中某些元素(可能一个也不删除)后剩余数字组成的序列,但不能改变数字间相对顺序。比方说,2,3,5 是 1,2,3,4,5 的一个子序列而 1,5,3 不是。

示例 1:

输入:nums1 = 2,1,-2,5, nums2 = 3,0,-6

输出:18

解释:从 nums1 中得到子序列 2,-2 ,从 nums2 中得到子序列 3,-6 。

它们的点积为 (23 + (-2)(-6)) = 18 。

示例 2:

输入:nums1 = 3,-2, nums2 = 2,-6,7

输出:21

解释:从 nums1 中得到子序列 3 ,从 nums2 中得到子序列 7 。

它们的点积为 (3*7) = 21 。

示例 3:

输入:nums1 = -1,-1, nums2 = 1,1

输出:-1

解释:从 nums1 中得到子序列 -1 ,从 nums2 中得到子序列 1 。

它们的点积为 -1 。

提示:

1 <= nums1.length, nums2.length <= 500

-1000 <= nums1i, nums2i <= 100

动态规划

cpp 复制代码
class Solution {
public:
    int maxDotProduct(vector<int>& nums1, vector<int>& nums2) {
        int m = nums1.size(), n = nums2.size();
        // 初始化 dp 数组为一个极小的值 INT_MIN,因为点积可能为负数
        vector<vector<int>> dp(m+1, vector<int>(n+1, INT_MIN));

        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                int product = nums1[i-1] * nums2[j-1];
                dp[i][j] = max({
                    product,                 // 只选择当前元素对
                    dp[i-1][j],              // 不选择 nums1[i-1]
                    dp[i][j-1],              // 不选择 nums2[j-1]
                    dp[i-1][j-1] == INT_MIN ? product : dp[i-1][j-1] + product // 检查溢出
                });
            }
        }

        return dp[m][n];
    }
};

这道题是LCS的变形,dpij 表示使用 nums1 的前 i 个元素和 nums2 的前 j 个元素时,能够得到的最大点积。

在计算dpij的时候有四种情况:

一种是我们只选择product这个元素对,

一种是不选择当前元素对,由dpi-1j的状态转移而来。

一种是不选择当前元素对,由dpij-1的状态转移而来。

一种是选择当前元素对,并且对dpi-1j-1检查是否是INT_MIN情况,防止出现k为负数时的溢出。然后由之前的状态dpi-1j-1加上该元素对。

由于我们要求的是最大点积,那么就从这四种情况中选取最大的情况。

最后返回dpmn。

相关推荐
I_belong_to_jesus10 小时前
C++关于分支预测的优化1
开发语言·c++·算法
Code_Solitude17 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司17 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
文丑颜不良啊18 小时前
LeetCode2821~2840题目解析
java·leetcode
YLCHUP19 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
思麟呀20 小时前
背包DP(01背包+完全背包)
c++·算法
笑容掩饰我的失落21 小时前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法
Pniubi1 天前
力扣24. 两两交换链表中的节点(递归)
算法·leetcode·链表
꧁细听勿语情꧂1 天前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法