CCPC 2018 网络赛 hdoj6447 YJJ's Salesman(Java版)

最近做的一个题,用了三个知识点,离散化,简单dp,线段树或树状数组来维护最大值。emmm,参考的别人的c++的代码该的Java代码用的线段树维护。。。然后超时了,用了快读还是超时。然后参考另外的一个用树状数组维护的代码,不加快读还是超时,加了快读就1.3ms过了,感觉差距好大啊,对Java太不友好了,感觉输入数据最多10^6
而已。看来以后超过10^5都要用快读模版了。
做了这道题,新学了离散化和树状数组两个知识点,开心。
做法就是排序y坐标之后,离散化y坐标,然后横坐标升序,纵坐标升序,一个简单的dp就行了
AC代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;


/*
 * 刚开始想用建图做,结果wa了,看了网上的题解,说用树状数组,维护区间最大值就行。
 */
public class hdoj6447 {
	static class point implements Comparable<point>{
		int x,y,v;
		point(int x,int y,int v){
			this.x=x;
			this.y=y;
			this.v=v;
		}
		@Override
		public int compareTo(point p) {
			if(this.x==p.x)
				return this.y-p.y;
			else
				return this.x-p.x;
		}
		
	}
	static int maxx=100010;
	static point p[]=new point[maxx];
	static int c[]=new int[maxx];
	static int yy[]=new int[maxx];
	static int dp[]=new int[maxx];
	static int LowerBound(int x[],int l,int r,int v){
		while(l<r){
			int mid=l+(r-l)/2;
			if(x[mid]>=v){
				r=mid;
			}else{ 
				l=mid+1;
			}
		}
		return l;
	}
	static int max(int a,int b){
		return a>b?a:b;
	}
	static void add(int i,int n,int v){
		for(;i<=n;i+=i&(-i)){
			c[i]=max(v,c[i]);
		}
	}
	static int query(int i){
		int res=0;
		for(;i!=0;i-=i&(-i)){
			res=max(res,c[i]);
		}
		return res;
	}
	 static class InputReader {  
	        BufferedReader br;   
	        public InputReader(InputStream stream) {  
	            br = new BufferedReader(new InputStreamReader(stream));  
	        }   
	        public int nextInt() throws IOException {  
	            int c = br.read();  
	            while (c <= 32) {  
	                c = br.read();  
	            }  
	            boolean negative = false;  
	            if (c == '-') {  
	                negative = true;  
	                c = br.read();  
	            }  
	            int x = 0;  
	            while (c > 32) {  
	                x = x * 10 + c - '0';  
	                c = br.read();  
	            }  
	            return negative ? -x : x;  
	        }   
	        public long nextLong() throws IOException {  
	            int c = br.read();  
	            while (c <= 32) {  
	                c = br.read();  
	            }  
	            boolean negative = false;  
	            if (c == '-') {  
	                negative = true;  
	                c = br.read();  
	            }  
	            long x = 0;  
	            while (c > 32) {  
	                x = x * 10 + c - '0';  
	                c = br.read();  
	            }  
	            return negative ? -x : x;  
	        }    
	        public String next() throws IOException {  
	            int c = br.read();  
	            while (c <= 32) {  
	                c = br.read();  
	            }  
	            StringBuilder sb = new StringBuilder();  
	            while (c > 32) {  
	                sb.append((char) c);  
	                c = br.read();  
	            }  
	            return sb.toString();  
	        }    
	        public double nextDouble() throws IOException {  
	            return Double.parseDouble(next());  
	        }  
	    }  
	 static InputReader in;  
	 static PrintWriter out;
	public static void main(String[] args) throws IOException{
		in = new InputReader(System.in);  
        out = new PrintWriter(System.out); 
		int t=in.nextInt();
		while(t-->0){
			int n=in.nextInt();
			for(int i=0;i<n;i++){
				int x=in.nextInt();
				int y=in.nextInt();
				int v=in.nextInt();
				p[i]=new point(x,y,v);
				yy[i]=y;
			}
			Arrays.sort(yy,0,n);
			for(int i=0;i<n;i++){
				p[i].y=LowerBound(yy, 0, n-1, p[i].y)+1;//离散化
			}
			Arrays.sort(p,0,n);
			Arrays.fill(dp, 0);
			Arrays.fill(c, 0);
			dp[0]=p[0].v;
			int ans=dp[0];
			int now=0;
			for(int i=1;i<n;i++){
				while(p[i].x!=p[now].x){
					add(p[now].y,n,dp[now]);
					now++;
				}
				dp[i]=query(p[i].y-1)+p[i].v;
				ans=max(ans,dp[i]);
			}
			System.out.println(ans);
		}
		out.close();
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值