leetcode-53-最大子序和

53. 最大子序和
leetcode-53-最大子序和_第1张图片
这里采用了dp的方法,但是还有更加简单的方法。分治法的效率更为高效。
dp的解决代码如下:

关于使用动态规划,我们不妨用一个小的模拟去简要说明。还是那句话:dp的思想是状态方程和状态条件。
dp有别于贪心的思想,贪心算是一种狠人,只要极值。但是dp是那种柔中带钢的,看谁走到最后的感觉。

还是先介绍本题的思想吧:
dp[i]表示nums[i]结尾的最大连续子序列和。

①:如果只有一个元素,那么dp[i]=nums[i]
②:如果有多个元素。选取序列,索引下标为[i,j]
    第一种情况;最大和s=sum(nums.begin(),nums.end())
    第二种情况:dp[i]=max(nums[i],nums[i]+dp[i-1])
如果理解第二种情况呢?举个栗子:
nums[]={-2,11,-4,13,-5,-2}
dp[0]=nums[0]=-2   其实这就是边界条件
dp[1]=11=nums[1]=max(dp[1],dp[1]+nums[1-1])
dp[2]=11+(-4)=7=max(dp[2],dp[2]+nums[2-1])=max(-4,11+(-4))=7
dp[3]=11+(-4)+13=max(dp[3],dp[1]+nums[3-1])=max(7,13+7)=20



模拟过程如下

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        vector<int> dp(nums.size());
        dp[0]=nums[0];//算是一个边界条件
        for(int i=1;i<nums.size();i++){
            dp[i]=max(nums[i],nums[i]+dp[i-1]);
        }
        return *std::max_element(dp.begin(),dp.end());
    }
};

用dev写出的完整代码,这个方式一个是很好的。
**最大连续子序列和**考得太多了,leetcode,pat都有。注意:使用max_element(),它是一个迭代器,而且使用该模板函数需要引入头文件algorithm

#include 
#include 
#include 
using namespace std;
int mss(vector<int>& v){
	vector<int> dp(v.size());
	dp[0]=v[0];
	for(int i=1;i<=v.size();i++){
		dp[i]=max(v[i],dp[i-1]+v[i]);
	}
	return *max_element(dp.begin(),dp.end());
}
int main(){
	int n;
	cin>>n;
	vector<int> v;
	for(int i=0;i<n;i++){
		int x;
		cin>>x;
		v.push_back(x);
	}
	int sum=mss(v);
	cout<<sum;
	return 0;
}

pat的1007 Maximum Subsequence Sum (25分)
leetcode-53-最大子序和_第2张图片

题解如下:

在这里插入代码片

你可能感兴趣的:(leetcode,算法,c++,leetcode,数据结构)