Kの整数のシーケンス所与{N 1、N 2、...、N K}。連続的なサブシーケンスは、{N I、N I + 1、...、N jを}1≤i≤j≤Kであると定義されます。最大のサブシーケンスは、その要素の最大の合計を持っている連続サブシーケンスです。例えば、{、-2、11 -4、13 -5、-2}のシーケンスを与え、その最大のサブシーケンスは、最大合計が20であると{11、-4、13}です。
今、あなたは、一緒に第一および最大サブシーケンスの最後の数字で、最大の合計を見つけることになっています。
入力仕様:
各入力ファイルには、1つのテストケースが含まれています。各ケースは2行を占めています。最初の行は、正の整数K(≤10000)を含みます。2行目は空白で区切られた、K番号を含んでいます。
出力仕様:
各テストケース1つのライン最大和に出力するため、一緒に第一及び最大サブシーケンスの最後の番号を持ちます。数字は1つのスペースで区切る必要がありますが、行の末尾に余分なスペースがあってはなりません。最大サブシーケンスは、固有、出力iとj(試料場合によって示されるように)最も小さいインデックスを有するものでない場合に。すべてのK番号が負の場合、その最大値の合計が0になるように定義され、そしてあなたが最初に全体のシーケンスの最後の番号を出力することになっています。
サンプル入力:
10
-10 1 2 3 4 -5 -23 3 7 -21
サンプル出力:
10 1 4
制限時間:200ミリ秒
メモリ制限:64メガバイト
コード:言及したオンラインカリキュラムのアプローチを使用して
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int k = in.nextInt();//输入正整数K
int[] nums = new int[k];
for (int i=0; i<k; i++) {//输入K个整数
nums[i]=in.nextInt();
}
in.close();
MaxSubseqSum maxSum = new MaxSubseqSum();
int[] result = maxSum.maxSubseqSum2(nums, k);
for(int i=0;i<result.length;i++){//输出结果,以空格分隔
System.out.print(result[i]);
if(i<result.length-1){
System.out.print(" ");
}
}
}
}
class MaxSubseqSum {
//在线处理法
public int[] maxSubseqSum2(int[] a, int n){
int thisSum = 0, maxSum = 0, reSum = 0;
int first = a[0], last = a[n-1];
int start = 0, end = 0;
boolean flag = false;
for(int i=0; i<n; i++){
thisSum += a[i];
if(thisSum > maxSum){
maxSum = thisSum;
end = i;
}else if(thisSum < 0){
thisSum = 0;
}
if(a[i] == 0){
flag = true;
}
}
for(int j=end; j>=0; j--){
reSum += a[j];
if(reSum == maxSum){
start = j;
if(a[j] >= 0) {//因为要求最大子列和不唯一时,输出的first和last值的下标要最小,故当最大子列和前面有0时,要把这些0加进来
continue;
}
}
}
if(maxSum > 0){
first = a[start];
last = a[end];
}else if(maxSum == 0){//maxSum为0存在两种情况:一种是所有整数都为负数,此时first和last分别为输入数列的首尾值;另一种是负数和0的组合,此时无论0的位置和数量,first和last都是0,所以在上面遍历时增加flag变量以记录是否存在0
if(flag){
first = 0;
last = 0;
}
}
return (new int[] {maxSum,first,last});
}
}
結果:
最後のテストケース振れの問題が解決し、よりよい解決策を楽しみにすることができませんでした。
更新
C言語でアルゴリズムは少し、高効率動作の多くは、最後のケースは、渡されました。
#include<stdio.h>
int main(){
int n;
int thisSum = 0, maxSum = 0, reSum = 0;
int start = 0, end = 0;//最大子列和首尾数字的下标
int first, last;//最大子列和的首尾数字
int flag = 0;//用来判断输入数字都是负数或零的情况
scanf("%d",&n);
int nums[n];
for( int i = 0; i < n; i++ ){
scanf("%d", &nums[i]);
thisSum += nums[i];
if( thisSum > maxSum ){
maxSum = thisSum;
end = i;
}
else if( thisSum < 0){
thisSum = 0;
}
if( nums[i] == 0 ){
flag = 1;
}
}
for( int j = end; j >= 0; j-- ){
reSum += nums[j];
if( reSum == maxSum ){
start = j;
if( nums[j-1] == 0 ){
continue;
}
}
}
first = nums[start];
last = nums[end];
if( maxSum == 0 ){
if( flag ){//输入数字是负数和零的组合
first = last = 0;
}else{//输入数字都是负数
first = nums[0];
last = nums[n-1];
}
}
printf("%d %d %d", maxSum, first, last);
return 0;
}