求一个序列的最大子序列和,这个可以有几种方法都可以去求解,这里我提供两种方法给大家。
假如这个序列是{1,-2,3,4},显然最大子序列和是7,那么这个要怎么去计算呢?
第一种方法就是顺序求取,可以先算一下只有一个元素的最大值是多少,再算一下连续两个元素的最大值是多少,再算一下连续三个元素的最大值是多少 ,直到n个元素全部都取完。用一个数组来保存连续一个,连续两个,连续n个的和的最大值,代码如下。
#include<iostream> using namespace std; const int N=-1e6+2; int main() {int n;cin >> n;int a[n];for(int i=0;i<n;i++){cin >> a[i];}int b[n];for(int i=0;i<n;i++){b[i]=N;for(int j=0;j<n-i;j++){int sum=0;for(int k=j;k<=j+i;k++){sum+=a[k];}if(sum>b[i]){b[i]=sum;}}}int m=b[0];for(int i=1;i<n;i++){if(m<b[i]){m=b[i];}}cout << m;return 0; }
为了提高效率,可以用两个for就可以实现,最大值不用数组表示,用一个变量max1,保存一下。
#include<iostream> const int N=1e6+1; using namespace std; int main() {int n;cin >> n;int a[n];for(int i=0;i<n;i++){cin >> a[i];}int max1=-N;for(int i=0;i<n;i++){int sum=0;for(int j=i;j<n;j++){sum+=a[j];if(max1<sum){max1=sum;}}}cout << max1;return 0; }
最后,给大家提供一下最简单的方法,用动态规划就可以做,做动态规划最重要的就是要找到状态转移方程,这个问题的状态转移方程就是
dp[i]=a[i]+dp[i-1]或者是dp[i]=a[i],代码如下
#include<iostream>
#include<algorithm>
const int N=1e6;
using namespace std;
int main()
{int n;cin >> n;int a[n];int dp[n];for(int i=0;i<n;i++){cin >> a[i];dp[i]=a[i];}int max1=-N;for(int i=1;i<n;i++){dp[i]=max(dp[i-1]+a[i],a[i]);if(max1<dp[i]){max1=dp[i];}}cout << max1;return 0;
}
这个只用了一个for就可以实现了,效率相比前面几个都提高了不少。