HDU-1003 Max Sum 解题报告

此题是一道求最大子数列的题,算是新手的第一道坎

此题用到了一个比较基础的算法:

public class MaximumSubsequence {
	
	public int maximumSubsequence(int[] a){
		int n = a.length;
		int thisSum = 0;
		int maxSum = 0;
		for(int i = 0; i < n; i++){
			thisSum += a[i];
			if(thisSum > maxSum){
				maxSum = thisSum;
			} else if(thisSum < 0) {
				thisSum = 0;
			}
		}
		return maxSum;
	}
}

这个算法的正确性毋庸置疑,只是需要一些时间理解与分析

具体的分析我会写在以后的算法分析专栏里

还有一种算法也能解决此类问题:分治法

分治法的强大型也是毋庸置疑的,许多问题都能用分治法来解决,而且分治法的时间复杂度为 O(n*logn)

是一个非常强大的算法

《=================================================================》

我使用的是第一种算法,因为他的核心代码量较小且时间复杂度仅为线性级-O(n)

但是这个算法目前并不能解决这道题

因为题目要求我们输出的最大子数列的 左坐标、右坐标、累加值

而这个算法目前只能得到累加值

所以需要一些操作来存储左右的坐标

其中需要注意的是:

1.输出格式(如果因为输出格式而错的话就太冤了)

2.如果有多个最大子数列,应取第一个为输出

3.在本题中 最大字数列 不包括 空数列  所以如果有一个 全负数组  那么最大应为最大的那个负数(所以代码中有许多改动的地方)

代码:

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int t = sc.nextInt();
		for (int i = 1; i <= t; i++) {
			int[] x = new int[100005];
			int n = sc.nextInt();
			for (int j = 1; j <= n; j++) {
				x[j] = sc.nextInt();
			}

			int thisSum = 0;
			int maxSum = -999999;
			int maxLeft = 0;
			int maxRight = 0;
			int left = 0;
			int right = 0;

			for (int j = 1; j <= n; j++) {
				if (j == 1) {
					left = right = 1;
				} else {
					right++;
				}
				thisSum += x[j];
				if (thisSum > maxSum) {
					maxSum = thisSum;
					maxLeft = left;
					maxRight = right;
				}
				if (thisSum < 0) {
					thisSum = 0;
					left = j + 1;
				}
			}
			System.out.println("Case " + i + ":");
			System.out.println(maxSum + " " + maxLeft + " " + maxRight);
			if (i != t) {
				System.out.println();
			}
		}
	}
}

如果你感觉都差不多了,却仍然WA,可以取本题的讨论区,里面有很多大佬给出的样例

总有一组样例能解决你的问题

猜你喜欢

转载自blog.csdn.net/Timo_Max/article/details/81459100