杭電OJ 1003題題目連結:點擊開啟連結
本題思路: 為了避免複雜的判斷,將測試案例全部為負數的情況單獨處理。
(1)如果某個測試案例全部為負數,則遍曆資料,找到最大的數,記錄下標,該下標既是子序列的開始下標,也是結束下標。
(2)如果某個測試案例不全為負,則採用動態規劃的方法,計算一系列的子序列和。具體方法如下:假如測試案例(用nums[5]數組儲存)為5 6 -1 5 4 -7,使用長度為5的數組sums儲存“和”的中間結果,設定sums[0]=6,sums[1]~sum[4]的值使用迴圈,通過動態計算然後賦值。例如,設定i為迴圈變數,如果sums[i-1] 為負,則sums[i]賦值為nums[i],也就是說不加上前面的“中間和”(因為前面的中間和為負嘛,所以加上這個負的中間和就找不到最大值了);如果sums[i-1]>=0,則sums[i]在此基礎上加上nums[i](如此非負數的累加才能找到最大值嘛,此時nums[i]其實就是某一個子序列的和,比如可能是子序列5+6+(-1)+5的和)。按照這種方法將sums[0]---sums[4]全部賦值完畢後,遍曆,最大的數即為要找的最大值。最大值的下標即為子序列的結束下標,從最大值的下標(結束值下標)向前找到第一個負數,也就找到了子序列的開始下標(因為如果nums[k]為負,則在nums[k+1]賦值的時候,就會放棄k之前的“中間和”,重新開始找最大值,所以該位置為子序列的分界點)。
本題AC範例程式碼如下:
import java.io.BufferedInputStream;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner cin = new Scanner(new BufferedInputStream(System.in));int count = cin.nextInt();//測試案例是否全部為負數boolean isNegative = true;for (int i = 0; i<count; i++) {int rowCount = cin.nextInt();// 使用數組nums儲存輸入的資料int[] nums = new int[rowCount];for(int j=0; j<rowCount; j++){int num = cin.nextInt();if(isNegative==true && num > 0){isNegative = false;}nums[j] = num;}//重複使用nums數組儲存相加的中間結果for (int j = 1; j < rowCount; j++) {if (nums[j - 1] >= 0) {nums[j] += nums[j - 1];}//其他情況,nums[j]的值不變}// 遍曆中間結果數組nums,找到最大的數max即為子序列最大和;//(注意:找第一個最大的數,nums數組可能有多個數max)// 該子序列起始位置為:數max向前找到第一個負數,然後加1;// 該子序列的結束位置為:數max所在的位置。int max = nums[0];// 使用beginFlag、endFlag記錄開始和結束下標int beginFlag = 0;int endFlag = 0;for (int k = 0; k < rowCount; k++) {if (nums[k] > max) {max = nums[k];// 隨著最大值更新的 “結束下標值”,迴圈結束後,endFlag即為正確的結束下標endFlag = k;}}// 尋找開始下標:從最終結束下標向前遍曆nums數組,向前找到第一個負數,注意找到後需要加1才是正確的開始下標// 特殊情況考慮:全為負數;if(isNegative){beginFlag = endFlag;} else {for (int k = endFlag-1; k >= 0; k--) {if (nums[k] < 0) {beginFlag = k + 1;break;}}}// 按照要求的格式進行輸出// 第一行if (i == 0) {System.out.println("Case " + (i + 1) + ":");System.out.print(max + " ");System.out.print(beginFlag + 1 + " ");System.out.println(endFlag + 1);}// 第二行即之後else {System.out.println();System.out.println("Case " + (i + 1) + ":");System.out.print(max + " ");System.out.print(beginFlag + 1 + " ");System.out.println(endFlag + 1);}}cin.close();}}
順便給出一些測試案例和正確的答案吼:
8
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
3 -2 1 -2
3 -2 -2 -2
7 -3 5 -7 3 4 -1 5
4 -3 -5 -2 -1
3 -3 -2 -7
4 0 0 0 0
Case 1:
14 1 4
Case 2:
7 1 6
Case 3:
1 2 2
Case 4:
-2 1 1
Case 5:
11 4 7
Case 6:
-1 4 4
Case 7:
-2 2 2
Case 8:
0 1 1
歡迎大家評論指正討論,不喜勿噴。