問題の説明は、
シーケンス[1]、[2]、[3] ... [n]を考えると、あなたの仕事は、サブシーケンスの最大合計を計算することです。例えば、(6、-1,5,4、-7)が与えられると、このシーケンスの最大合計は、6 +(-1)+ 5 + 4 = 14です。
入力
入力の最初の行は、テストケースの数を意味する整数Tを(1 <= T <= 20)を含みます。次いで、Tラインは、次の各ライン番号N(1 <= N <= 100000)で始まり、その後N整数(すべての整数は-1000と1000の間である)に続きます。
出力
各テストケースの場合は、あなたは、出力の2行をする必要があります。最初の行は、「ケース#:」で、#は、テストケースの数を意味しています。2行目は三つの整数、配列中の最大合計、サブシーケンスの開始位置は、サブシーケンスの終了位置を含んでいます。以上の結果、出力最初のものがある場合。出力2例の間に空白行。
サンプル入力
2
5 6 -1 5 4 -7
7 0 6 -1 1-6 7 -5
サンプル出力の
ケース1:
14 1 4
ケース2:
7 1 6
著者
Ignatius.L
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[100000][4];
//0是值,1是dp,2是起点,3是终点
int main(){
int t,n;
cin>>t;
for(int j=1;j<=t;j++){
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&dp[i][0]);
dp[i][1]=dp[i][0];
dp[i][2]=i;
dp[i][3]=i;
}
for(int i=2;i<=n;i++){
if(dp[i-1][1]+dp[i][1]>=dp[i][1]){
dp[i][1]+=dp[i-1][1];//总和++
dp[i][2]=dp[i-1][2];//起点等于上一个的起点
}
}
cout<<"Case "<<j<<":"<<endl;
int max=-9999999;
for(int i=1;i<=n;i++){
if(max<=dp[i][1])max=dp[i][1];
}
for(int i=1;i<=n;i++){
if(max==dp[i][1]){
cout<<dp[i][1]<<" "<<dp[i][2]<<" "<<dp[i][3]<<endl;
break;
}
}
if(j!=t)cout<<endl;
}
return 0;
}
これは、各位置のための最適な解決策を決定することである状態遷移方程式
if(dp[i-1][1]+dp[i][1]>=dp[i][1]){
dp[i][1]+=dp[i-1][1];//总和++
dp[i][2]=dp[i-1][2];//起点等于上一个的起点
}