题目大意是,给你一个数字序列,求其子串的最大和,注意是子串,子串是连续的字符
注意题目要求:If there are more than one result, output the first one. Output a blank line between two cases.
动规方程 dp[i]=(dp[i-1]+a[i]>a[i])?dp[i-1]+a[i]:a[i];
其实就等价于(dp[i-1]>0)?dp[i-1]+a[i]:a[i];
dp[i]即前i个数字的子串最大和
上代码
#include <iostream>
#include <string.h>
using namespace std;
int dp[100005],a[100005];
int main() {
int t,count=0;
cin>>t;
for(count=1; count<=t; count++) {
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
int i,n,max,start,end;
cin>>n;
for(i=1; i<=n; i++)
cin>>a[i];
dp[1]=max=a[1];
for(i=2; i<=n; i++) {
dp[i]=dp[i-1]>0?dp[i-1]+a[i]:a[i];
}
end=1;
for(i=2; i<=n; i++) {
if(max<dp[i]) {
max=dp[i];
end=i;
}
}
int sum=0;
for(i=end; i>=1; i--) {
sum+=a[i];
if(sum==max) start=i; //此处不能break,因为题目要求是找第一个
}
cout<<"Case "<<count<<":"<<endl;
cout<<max<<" "<<start<<" "<<end<<endl;
if(count<t)
cout<<endl;
}
return 0;
}
第二种代码更简洁
#include <iostream>
using namespace std;
int main() {
int t,count=0;
cin>>t;
for(count=1; count<=t; count++) {
int n,x,sum,max,start,end,nowstart;
cin>>n>>x;
sum=max=x;
start=end=nowstart=1;
for(int i=2; i<=n; i++) {
cin>>x;
if(sum+x<x) { //sum是指前i个数字的子串最大和 sum<0,更新
sum=x;
nowstart=i;
} else {
sum+=x;
//end=i; 此处不能记录end,因为
// If there are more than one result, output the first one. Output a blank line between two cases.
}
if(sum>max) {
max=sum;
start=nowstart;
end=i;
}
}
cout<<"Case "<<count<<":"<<endl;
cout<<max<<" "<<start<<" "<<end<<endl;
if(count<t)
cout<<endl;
}
return 0;
}