HOJ 1003题 题解

来源:互联网 发布:子弹图纸尺寸图片编程 编辑:程序博客网 时间:2024/04/30 12:00

     杭电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


      欢迎大家评论指正讨论,不喜勿喷。

0 0
原创粉丝点击