1065 最小正子段和(貪心)
阿新 • • 發佈:2018-11-30
1065 最小正子段和
1 秒 131,072 KB 20 分 3 級題
思路:
一開始以為是動態規劃,但是求的是大於0的子段和,那麼只能暴力求解了
預處理資料,儲存為字首和陣列,然後進行排序,在這之前需要儲存排序前的位置d[i]
然後最重要的,迴圈排完的陣列a[i]
判斷 a[i]-a[i-1]>0 && d[i] > d[i-1]
排序可以吧相差較小的放在一起
判斷位置是因為要符合邏輯
列舉完陣列,最小的a[i]-a[i-1]
即為所求
程式碼:
package _51_node.greedy; import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class ex_1065 { /** * 1065 最小正子段和 * 1 秒 131,072 KB 20 分 3 級題 * N個整陣列成的序列a[1],a[2],a[3],…,a[n],從中選出一個子序列(a[i],a[i+1],…a[j]), * 使這個子序列的和>0,並且這個和是所有和>0的子序列中最小的。例如:4,-1,5,-2,-1,2,6,-2。-1,5,-2,-1,序列和為1,是最小的。 * * 計算字首和,標記加的位置,根據字首和排序, * 根據排序後的順序後-前,並判斷原來位置 後 在 前 的前面 * nlog(n) * * @param args */ public static void main(String[] args) { final long INF = Long.MAX_VALUE; ; Scanner cin = new Scanner(System.in); int n = cin.nextInt(); ArrayList<Point> arrayList = new ArrayList<>(); long index = 0; for (int i = 1; i <= n; i++) { long x = cin.nextInt(); arrayList.add(new Point(i, x + index)); index += x; } arrayList.add(new Point(0, 0)); cin.close(); Collections.sort(arrayList); long ans = INF; for (int i = 1; i < arrayList.size(); i++) { // System.out.println(arrayList.get(i).value); Point p1 = arrayList.get(i - 1); Point p2 = arrayList.get(i); if (p1.site < p2.site) { if (p2.value - p1.value > 0) { // System.out.println(p2.value - p1.value); ans = Math.min(ans, p2.value - p1.value); } } } System.out.println(ans); } static class Point implements Comparable<Point> { int site; long value; public Point(int site, long value) { this.site = site; this.value = value; } @Override public int compareTo(Point o) { if (value > o.value) return 1; else return -1; } } }