53. 最大子序和
这里采用了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 <iostream>
#include <vector>
#include <algorithm>
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分)
题解如下:
在这里插入代码片