求一個序列的最大子序列和,這個可以有幾種方法都可以去求解,這里我提供兩種方法給大家。
假如這個序列是{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就可以實現了,效率相比前面幾個都提高了不少。