题意:
按照顺序接收重量为 4, 3, 2, 1, 4的block时,可按照重量为4 –> 3 –>2 –> 1 的顺序推成塔,然后最后为了装饰塔顶,可以使用重量为4的block。
用例:
1
5
2 4
1 2
3 3
2 6
1 4
—> # 13
package indexTree;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.InputStreamReader;import java.util.Arrays;import java.util.Comparator;import java.util.StringTokenizer;public class 积木游戏3{static int T,N;static long[] indexTree;static block[] blockArr;static class block{int index;int w;int val;int max;public block(int index, int w, int val, int max) {this.index = index;this.w = w;this.val = val;this.max = max;}}static class compM implements Comparator<block>{@Overridepublic int compare(block o1, block o2) {if (o1.w != o2.w) {return o2.w-o1.w;}else {//此处的排序 当重量相同时 index 按照 降序排列// 因为题目中要求相同重量的不能叠放。return o2.index-o1.index;}}}public static void main(String[] args) throws Exception {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StringTokenizer st = new StringTokenizer(br.readLine());T = Integer.parseInt(st.nextToken());for (int i0 = 1; i0 <= T; i0++) {st = new StringTokenizer(br.readLine());N = Integer.parseInt(st.nextToken());blockArr = new block[N];for (int i = 0; i < N; i++) {st = new StringTokenizer(br.readLine());int weightTemp = Integer.parseInt(st.nextToken());int valTemp = Integer.parseInt(st.nextToken());blockArr[i] = new block(i,weightTemp, valTemp,0);}//获取当前点之后的最大值for (int i = N-2; i >=0; i--) {blockArr[i].max = Math.max(blockArr[i+1].max, blockArr[i+1].val);}Arrays.sort(blockArr,0,N,new compM());int lastNodeNum = 1;while(lastNodeNum < N) {lastNodeNum <<=1;}indexTree = new long[2*lastNodeNum];long ans = 0;for (int i = 0; i < N; i++) {long sum = query(lastNodeNum, lastNodeNum+blockArr[i].index)+blockArr[i].val;update(lastNodeNum+blockArr[i].index, sum);ans = Long.max(ans, sum+blockArr[i].max);}System.out.println("#"+i0+" "+ans);}}private static void update(int index, long val) {while (index > 0) {indexTree[index] = Math.max(val,indexTree[index]);index >>= 1;}}private static long query(int s, int e) {long max = 0;while (s <= e) {if (s % 2 == 1) max = Long.max(max, indexTree[s]);if (e % 2 == 0) max = Long.max(max, indexTree[e]);s = (s + 1) >> 1;e = (e - 1) >> 1;}return max;}}
