C\C++:PIPIOJ-最大連續子序列(並找到序列的位置)

題目鏈接:http://pipioj.online/problem.php?id=1008
題目描述

  • 給定 K 個整數的序列{ N1, N2, …, NK } ,其任意連續子序列可表示爲{ Ni, Ni+1,…,Nj} ,其中1 <= i<= j <= K。最大連續子序列是所有連續子序列中元素和最大的一個,例如給定序列{ -2, 11, -4, 13, -5, -2 } ,其最大連續子序列爲{ 11, -4, 13 } ,最大和爲20。編寫程序得到其中最大子序列的和並輸出該子序列的第一個和最後一個元素的下標。

輸入

  • 測試輸入包含若干測試用例,每個測試用例佔2 行,第 1 行給出正整數 K( <100000) ,第 2 行給出 K 個整數,每個整數的範圍-10000至10000 ,中間用空格分隔。

輸出

  • 對每個測試用例, 在 1 行裏輸出最大和、 最大連續子序列的第一個和最後一個元素的下標,中間用空格分隔。 如果最大連續子序列不唯一, 則輸出序號 i 和 j 最小的那個(如輸入樣例的第 2、3組)。若所有 K 個元素都是負數,則定義其最大和爲0,輸出"0 0 0"。

樣例輸入

  • 8
    6 -2 11 -4 13 -5 -2 10
    20
    -10 1 2 3 4 -5 -23 3 7 -21 6 5 -8 3 2 5 0 1 10 3
    8
    -1 -5 -2 3 -1 0 -2 0
    4
    -1 -2 -4 -3

樣例輸出

  • 27 0 7
    27 10 19
    3 3 3
    0 0 0

分析:這裏採用動態規劃的思想實現,用一個數組S來保存當前下標位置的最大連續子序列的和,當輸入數組被遍歷一遍後,數組S的值就被更新,每一位都是當前下標位置的最大連續子序列的和。在遍歷輸入數組A時,判斷S[i-1]的是值是否大於0,因爲如果S[i-1]值小於等於0,就要被捨棄(一個數加上一個負數,只可能變小),此時S[i]就等於A[i]。因爲還要輸出序列的下標,所以這裏數組用結構體代替

代碼如下:

#include <cstdio>

struct Node {
	int x1, x2;
	int value;
}sum[100001], maxSum; // sum數組用來記錄最大連續子序列的和以及下標,maxSum是記錄最大的sum

int k, n;

int main() {
//	freopen("input.txt", "r", stdin);
	while(scanf("%d", &k) != EOF) {
		scanf("%d", &sum[0].value);
		sum[0].x1 = sum[0].x2 = 0;
		maxSum = sum[0];
//		printf("%d ", sum[0].value);

		for(int i = 1; i < k; i++) {
			scanf("%d", &n);
//			printf("%d ", n);
			if(sum[i-1].value <= 0) {  // 計算當前位置最大和 
				sum[i].value = n;
				sum[i].x1 = sum[i].x2 = i; // 更新下標
			} else {
				sum[i] = sum[i-1];
				sum[i].value += n;
				sum[i].x2++;
			}
			
			if(maxSum.value < sum[i].value) {
				maxSum = sum[i];
			} 
//			printf("%d ", sum[i].value);
		}
		
		if(maxSum.value > 0) {
			printf("%d %d %d\n", maxSum.value, maxSum.x1, maxSum.x2);
		} else {
			printf("0 0 0\n");
		}
	}
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章