其他分享
首页 > 其他分享> > “不相邻最大子序列和“

“不相邻最大子序列和“

作者:互联网

描述

给你一个数组,其长度为 n  ,在其中选出一个子序列,子序列中任意两个数不能有相邻的下标(子序列可以为空)

本题中子序列指在数组中任意挑选若干个数组成的数组。

数据范围:1 ≤n≤10^5,数组中所有数的值满足∣val∣≤2147483647

进阶:空间复杂度 O(1) , 时间复杂度 O(n)

示例1

输入:3,[1,2,3]

返回值:4

说明:有[],[1],[2],[3],[1,3] 4种选取方式其中[1,3]选取最优,答案为4

示例2

输入:4,[4,2,3,5]

返回值:9

说明:其中[4,5]的选取方案是在满足不同时选取相邻位置的数的情况下是最优的答案

示例3

输入:1,[-1]

返回值:0

说明:选择子序列为空最优

示例4

输入:5,[3,2,3,4,5]

返回值:11

说明:其中选择[3,3,5]的方案是最优的答案

备注:

输入的值在int范围内

 思路分析:

看到这题,很容易观察到这是一个包含子问题的,直接dp。

题目要求是不相邻的子序列值。 什么样子会帮助满足最大呢?
1,序列包含尽可能多的数
2,序列包含尽可能大的数。
考虑不相邻的话,要不要加入第i个数,需要考虑的问题是它前一个i-1 要不要加入,至于i-2则不需要考虑,因为加入第i个数必然可以加入不相邻的i-2 。换句话说,你不会跳过3个数。
换成代码就是 dp[i+3] = max(dp[i+2], dp[i+1]+arr[i])

解法一:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算
     * @param n int整型 数组的长度
     * @param array int整型vector 长度为n的数组
     * @return long长整型
     */
    long long subsequence(int n, vector<int>& array) {
        // write code here
        long long dp1 = 0;
        long long dp2 = 0;
        for(auto &it :array)
        {
            long long dp3 = max(dp1 + it, dp2);
            dp1 = dp2;
            dp2 = dp3;
        }
        return dp2;
    }
};

解法二:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 计算
     * @param n int整型 数组的长度
     * @param array int整型vector 长度为n的数组
     * @return long长整型
     */
    long long subsequence(int n, vector<int>& array) {
        // write code here
        vector<long long> dp(n+1);
        dp[0]=0;
        dp[1]=array[0];
        long long mymax=0;
        for(int i=2;i<=n;i++){
            dp[i] = max(dp[i-1],dp[i-2]+array[i-1]);
            if(mymax<dp[i])
                mymax=dp[i];
        }
        if(dp[1]>mymax)
            mymax=dp[1];
        return mymax;
    }
};

 

标签:最大,int,long,相邻,数组,序列,array,dp
来源: https://blog.csdn.net/yizhizainulii/article/details/121948218