【一隻蒟蒻的刷題歷程】 【PAT (Advanced Level) Practice】 1007 最大子序列總和

Given a sequence of K integers { N​1​​, N​2​​, …, N​K​​ }. A continuous subsequence is defined to be { N​i​​, N​i+1​​, …, N​j​​ } where 1≤i≤j≤K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (≤10000). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10
-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4


題目大意:

1007最大子序列總和(25分)

給定一個由K個整數組成的序列{N-1,N 2,…,NK}。連續子序列定義爲{N i,N i + 1,…,N j}}其中1≤i≤j≤K。最大子序列是具有最大元素和的連續子序列。例如,給定序列{-2,11,-4,13,-5,-2},其最大子序列爲{11,-4,13},最大和爲20。

現在,您應該找到最大的和,以及最大子序列的第一個和最後一個數字。

輸入規格:

每個輸入文件包含一個測試用例。每個案例佔用兩行。第一行包含一個正整數K(≤10000)。第二行包含K個數字,以空格分隔。

輸出規格:

對於每個測試用例,在一行中輸出最大和,以及最大子序列的第一個和最後一個數字。數字必須用一個空格分隔,但行尾不能有多餘的空格。如果最大子序列不是唯一的,則輸出索引i和j最小的子序列(如示例情況所示)。如果所有K個數字均爲負,則其最大和定義爲0,並且應該輸出整個序列的第一個和最後一個數字。

樣本輸入:

10
-10 1 2 3 4 -5 -23 3 7 -21

樣本輸出


10 1 4


思路:

坑點4 和 5:
一個是所有數爲負數 ,輸出 0 第一個數 最後一個數;
例子:-2 -3 -5 輸出 0 -2 -5;
一個是至少有一個是0,其他都是負數或者0,輸出0 0 0;
例子:-2 0 -3 輸出 0 0 0;


代碼:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int maxn=10100;
int main() 
{
   int n,MAX=0,flag=0,flag1=0;  //兩個flag解決 坑點4和5
   int a[maxn],dp[maxn];   
   cin>>n; 
   for(int i=1;i<=n;i++)
   {
   	   cin>>a[i];
   	   if(a[i]>0) flag=1;   //flag=0 表示全部數都非正(0或負)
   	   if(a[i]==0) flag1=1; //記錄是否有0
   }
   
   if(flag1==1 && flag==0)  //有0 非正(0或負)
   {
   	  cout<<0<<" "<<0<<" "<<0;  //輸出0 0 0
	  return 0;
   }
   else if(flag==0 && flag==0) //無0 全負
   {
   	  cout<<0<<" "<<a[1]<<" "<<a[n];  //輸出0 第一個數 最後一個數
	  return 0;
   }
    dp[0]=0; //前0個數最大爲0
    
    int position;  //記錄最大子序列的最後一個數
    for(int i=1;i<=n;i++)
    {
    	dp[i] = max(a[i] , dp[i-1]+a[i]); 
    	//前i個最大子序列爲 max(第i個數,第i個數+前i-1個數的最大值)
    	if(MAX < dp[i]) //更新最大值
    	{
    		MAX=dp[i]; 
    		position=i; //更新位置
		}
	}
	//下面是爲了從最後一個數往前累加,直到等於MAX,就找到了第一個數
    int sum=0;   //總和
    int wei=position; //先把最後一個數記錄下來
	while(position)
	{
		sum+=a[position]; //累加
		if(sum==MAX) //和等於MAX,結束
		break;
		position--; //一定要放下面,如果放break前面就可能會多減1
	}  
    cout<<MAX<<" "<<a[position]<<" "<<a[wei]; //輸出
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章