首页 > 其他分享 >子数组最大累加和2

子数组最大累加和2

时间:2025-01-13 11:11:35浏览次数:1  
标签:最大 nums int max 累加 数组 dp size

[Algo] 子数组最大累加和2

1. 乘积最大子数组

// 1. 乘积最大子数组
// https://leetcode.cn/problems/maximum-product-subarray/
int maxProduct(vector<int>& nums) {
    int n = nums.size();
    vector<int> dp_min(n), dp_max(n);
    dp_min[0] = nums[0]; dp_max[0] = nums[0];
    int ans = dp_max[0];
    for (int i = 1; i < n; i++)
    {
        dp_min[i] = min(nums[i], min(nums[i] * dp_min[i - 1], nums[i] * dp_max[i - 1]));
        dp_max[i] = max(nums[i], max(nums[i] * dp_min[i - 1], nums[i] * dp_max[i - 1]));
        ans = max(ans, dp_max[i]);
    }
    return ans;
}

2. 子序列累加和必须被7整除的最大累加和

// 2. 子序列累加和必须被7整除的最大累加和
int maxSumDividedBy7(vector<int>& nums) {
    int n = nums.size();
    vector<vector<int>> dp(n + 1, vector<int>(7));
    // dp[i][j]: 前n个数中累加和模7为j的最大累加和, -1表示不存在
    dp[0][0] = 0;
    for (int j = 1; j < 7; j++) dp[0][j] = -1;
    for (int i = 1; i <= n; i++)
    {
        int cur = nums[i - 1] % 7;
        for (int j = 0; j < 7; j++)
        {
            int need = j >= cur ? j - cur : j + 7 - cur;
            dp[i][j] = dp[i - 1][j];
            if (dp[i - 1][need] != -1) dp[i][j] = max(dp[i - 1][j], nums[i - 1] + dp[i - 1][need]);
        }
    }
    return dp[n][0];
}

3. 魔法卷轴i

// 3. 魔法卷轴i
// 给定一个数组nums,其中可能有正、负、0
// 每个魔法卷轴可以把nums中连续的一段全变成0
// 你希望数组整体的累加和尽可能大
// 卷轴使不使用、使用多少随意,但一共只有2个魔法卷轴
// 请返回数组尽可能大的累加和
int magicScroll(vector<int> &nums)
{
    int p0 = 0;
    for (int num : nums) p0 += num; // p0: 不使用魔法卷轴的累加和

    vector<int> dp(nums.size());  // dp[i]: nums[0...i]使用一次魔法卷轴的最大累加和
    int prefix = nums[0], maxPrefix = max(0, nums[0]);
    for (int i = 1; i < nums.size(); i++)
    {
        dp[i] = max(nums[i] + dp[i - 1], maxPrefix);
        prefix += nums[i];
        maxPrefix = max(maxPrefix, prefix);
    }
    int p1 = dp[nums.size() - 1]; // p1: 使用1次魔法卷轴的最大累加和

    vector<int> dp_(nums.size()); // dp_[i]: nums[i...n-1]使用一次魔法卷轴的最大累加和
    dp_[nums.size() - 1] = 0;
    int suffix = nums[nums.size() - 1], maxSuffix = max(0, nums[nums.size() - 1]);
    for (int i = nums.size() - 2; i >= 0; i--)
    {
        dp_[i] = max(nums[i] + dp_[i + 1], maxSuffix);
        suffix += nums[i];
        maxSuffix = max(maxSuffix, suffix);
    }
    int p2 = INT32_MIN;
    for (int k = 1; k < nums.size() - 1; k++)
    p2 = max(p2, nums[k] + dp[k - 1] + dp_[k + 1]); // p2: 使用2次魔法卷轴的最大累加和

    return max(p0, max(p1, p2));
}

4. 魔法卷轴ii

// 4. 魔法卷轴ii
// 给定一个数组nums,
// 现在允许你随意选择数组连续一段进行翻转,也就是子数组逆序的调整
// 比如翻转[1,2,3,4,5,6]的[2~4]范围,得到的是[1,2,5,4,3,6]
// 返回必须随意翻转1次之后,子数组的最大累加和
int MagicScroll(vector<int> &nums)
{
    int n = nums.size();
    vector<int> original(n);
    original[n - 1] = nums[n - 1]; // original[i]: nums[i...n-1]中以i为开始位置的最大累加和
    for (int i = n - 2; i >= 0; i--) original[i] = max(nums[i], nums[i] + original[i + 1]);

    int end = nums[0], maxEnd = nums[0], ans = INT32_MIN;
    // end: nums[0...i]中以i为结束位置的最大累加和
    // maxEnd: nums[0...i]中的最大累加和
    for (int i = 1; i < n; i++)
    {
        ans = max(ans, maxEnd + original[i]);
        end = max(nums[i], nums[i] + end);
        maxEnd = max(maxEnd, end);
    }

    return max(ans, maxEnd);
}

标签:最大,nums,int,max,累加,数组,dp,size
From: https://www.cnblogs.com/yaoguyuan/p/18668241

相关文章

  • 树状数组【单点修改+区间查询】+二分
    https://codeforces.com/gym/580226/problem/H#include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'#definelowbit(x)x&(-x)usingll=longlong;usingpii=pair<int,int>;constdoublePI=acos(-1);constintN=2e5......
  • 树状数组【区间修改+单点查询】
    https://www.luogu.com.cn/problem/P3368#include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'#definelowbit(x)x&(-x)usingll=longlong;usingpii=pair<int,int>;constdoublePI=acos(-1);constintN=5e5+10......
  • 写一个获取数组的最大值、最小值的方法
    在前端开发中,获取数组的最大值和最小值是一个常见的需求。你可以使用JavaScript的Math.max()和Math.min()函数结合扩展运算符(...)来实现这个功能。以下是一个简单的示例:functiongetMaxAndMin(arr){if(!Array.isArray(arr)||arr.length===0){return{max:null,m......
  • 树状数组【模板】
    https://www.luogu.com.cn/problem/P3374#include<bits/stdc++.h>usingnamespacestd;#defineendl'\n'#definelowbit(x)x&(-x)usingll=longlong;usingpii=pair<int,int>;constdoublePI=acos(-1);constintN=5e5+10......
  • Python实现:两个朋友的最大共同行走距离
    问题背景Alan和Bob是住在城市中的两个邻居,他们的城市里只有三栋建筑:电影院、商店和他们的家。一天,他们一起去看电影,看完后他们决定继续讨论电影,但由于各自有不同的任务,他们的路径有所不同。Bob打算直接回家,而Alan则需要先去商店,再回家。在离开电影院后,他们决定一起走一段路,讨......
  • 算法-查找滑动窗口中的最大值-Go(滑动窗口)
    题目给定一个长度为n的数组num和滑动窗口的大小size,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5};针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个:{[2,3,4],2,6,2,5,1},{......
  • 算法-在数组中获取制定值的索引值-php(二分法)
    算法-在数组中获取制定值的索引值-php(二分法)<?php/***代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可***@paramnumsint整型一维数组*@paramtargetint整型*@returnint整型*/functionsearch($nums,$target){//......
  • 力扣-数组-219 存在重复元素Ⅱ
    解析同上一篇《力扣-数组-217存在重复元素》存储在重复元素的思路,重点是放在结构体里,保存之前的下标即可。代码classSolution{public:structmyNode{intindex;intvalue;};staticboolcmp(myNodea,myNodeb){return......
  • 算法4:长度最小的子数组
    一、前言题目链接:力扣题目链接给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl,numsl+1,...,numsr-1,numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。示例1:输入:tar......
  • 算法3:有序数组的平方
    一、前言题目链接:力扣题目链接给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。示例1:输入:nums=[-4,-1,0,3,10]输出:[0,1,9,16,100]解释:平方后,数组变为[16,1,0,9,100]排序后,数组变为[0,1,9,16,100]示......