求连续子序列的最大和:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int nmax=10010;
int a[nmax]; //存放序列
int dp[nmax];//存放以a[i]结尾的连续子序列的最大值
int main(int argc, char** argv) {
int n;
while(cin>>n){
for(int i=0;i<n;i++){
cin>>a[i];
}
dp[0]=a[0];
for(int i=1;i<n;i++){
dp[i]=max(a[i],dp[i-1]+a[i]);//a[i]这个数若比和还大,另起一单。
}
int ans=*max_element(dp,dp+n);
cout<<ans<<endl;
}
return 0;
}
/*
6
-2 11 -4 13 -5 -2
20
*/
求连续子序列的最大和及其左右区间:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int nmax=100000+10;
int a[nmax];
int dp[nmax];//必须以a[i]作为结尾的连续子序列的最大和
int l[nmax];//必须以a[i]作为结尾的连续子序列的左端点
int r[nmax];//必须以a[i]作为结尾的连续子序列的右端点
int main(int argc, char** argv) {
int t;
while(cin>>t){
while(t--){//t组测试数据
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
dp[i]=a[i];
}
l[0]=0;r[0]=0;
for(int i=1;i<n;i++){
//dp[i]=max(dp[i],dp[i-1]+a[i]);
if(dp[i-1]+a[i]>=dp[i]){
dp[i]=dp[i-1]+a[i];
l[i]=l[i-1];//左端点不变,右移右端点
r[i]=i;
}
else{
l[i]=i;//新起一个数
r[i]=i;
}
printf("dp[%d]=%d, l=%d, r=%d\n",i,dp[i],l[i],r[i]);
}
int ans=dp[0];
int pos=0;
for(int i=1;i<n;i++){
if(dp[i]>ans){
ans=dp[i];
pos=i;
}
}
cout<<ans<<" "<<l[pos]<<" "<<r[pos]<<endl;
}
}
return 0;
}
//6 2 7 -9 5 4 3 —— 12 0 5
//6 -1 -2 -3 1 2 3 —— 6 3 5
/*
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
------------------
14 0 3
7 0 5
*/