Intervals
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
reads the number of intervals, their end points and integers c1, ..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard output.Input
The first line of the input contains an integer n (1 <= n <= 50000) -- the number of intervals. The following n lines describe the intervals. The (i+1)-th line of the input contains three integers ai, bi and ci separated by single spaces and such that 0 <= ai <= bi <= 50000 and 1 <= ci <= bi - ai+1.
Output
The output contains exactly one integer equal to the minimal size of set Z sharing at least ci elements with interval [ai, bi], for each i=1,2,...,n.
Sample Input
5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1Sample Output
6思路:
- 贪心+树状数组
- 贪心策略:先对这些区间的结束位置进行排序,然后尽量选择该区间靠后的点。如果当前区间的起始位置大于上一个区间的结束位置,那么只能重新开始选点;否则需要数出当前区间的起始位置到上一个区间的结束位置已经有多少个点,如果数出的点已经大于等于当前区间所要求的点,直接continue;否则还需要从当前区间的结束位置数出还需且未被标记过的点
- 但是仅仅使用以上贪心策略会超时,时间复杂度在O(N^2),如果我们想知道当前区间到上一个区间的结束位置已经有多少点的话,需要O(N)的复杂度,但是可以使用树状数组进行优化,将时间复杂度降低到O(logN)
AcCode:
import java.util.Arrays; import java.util.Scanner; public class Main{ //区间内有多少个点使用树状数组进行维护 private static class TreeArrays{ int[] arr = null; int[] treeArr = null; public TreeArrays(int n) { this.arr = new int[n];//原数组 treeArr = new int[n];//树状数组 } public void update(int i,int val) { int del = val-arr[i]; arr[i] = val; while(i<treeArr.length) { treeArr[i] = treeArr[i] + del; i = i+lowbit(i); } } public int sum(int i,int j) { return sum(j)-sum(i-1); } public int sum(int i) { int sum = 0; while(i>0) { sum+=treeArr[i]; i = i-lowbit(i); } return sum; } public int lowbit(int i) { return i&-i; } } private static class Qj implements Comparable<Qj> { int beginIndex; int endIndex; int needPoint; public Qj(int beginIndex, int endIndex, int needPoint) { this.beginIndex = beginIndex; this.endIndex = endIndex; this.needPoint = needPoint; } @Override public int compareTo(Qj o) { int res = endIndex - o.endIndex; if (res == 0) { return beginIndex - o.beginIndex; } else { return res; } } @Override public String toString() { // TODO Auto-generated method stub return beginIndex + " " + endIndex + " " + needPoint; } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); Qj[] qjs = new Qj[n + 1]; for (int i = 1; i <= n; i++) { qjs[i] = new Qj(in.nextInt(), in.nextInt(), in.nextInt()); } Arrays.sort(qjs, 1, qjs.length); // for (Qj b : qjs) { // System.out.println(b); // } TreeArrays treeArrays = new TreeArrays(qjs[qjs.length - 1].endIndex + 1); // boolean[] isChoice = new boolean[qjs[qjs.length - 1].endIndex + 1]; long count = qjs[1].needPoint; int lastIndex = qjs[1].endIndex; // 初始化 for (int i = (int) (lastIndex - count + 1); i <= lastIndex; i++) { treeArrays.update(i, 1); } for (int i = 2; i < qjs.length; i++) { if(qjs[i].beginIndex>lastIndex) { count+=qjs[i].needPoint; lastIndex = qjs[i].endIndex; for (int j = qjs[i].endIndex; j >0 && j>=qjs[i].endIndex-qjs[i].needPoint+1; j--) { treeArrays.update(j, 1); } }else { int realdyPoint = treeArrays.sum(qjs[i].beginIndex, lastIndex);//已经有多少个点 // for (int j = qjs[i].beginIndex; j <=lastIndex; j++) { // if(treeArrays.arr[])realdyPoint++; // } int syPoint = qjs[i].needPoint-realdyPoint; if(syPoint<=0)continue; lastIndex = qjs[i].endIndex; count+=syPoint; for (int j = qjs[i].endIndex; j >0 && j>=qjs[i].endIndex-qjs[i].needPoint+1 && syPoint>0; j--) { if(treeArrays.arr[j]==1)continue; syPoint--; treeArrays.update(j, 1); } } } System.out.println(count); } }
Intervals(POJ-1201)
最新推荐文章于 2021-05-04 00:09:04 发布