YJJ's Salesman(树状数组,离散化,dp)

YJJ's Salesman

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 253    Accepted Submission(s): 62

 

Problem Description

YJJ is a salesman who has traveled through western country. YJJ is always on journey. Either is he at the destination, or on the way to destination.
One day, he is going to travel from city A to southeastern city B. Let us assume that A is (0,0) on the rectangle map and B (109,109). YJJ is so busy so he never turn back or go twice the same way, he will only move to east, south or southeast, which means, if YJJ is at (x,y) now (0≤x≤109,0≤y≤109), he will only forward to (x+1,y), (x,y+1) or (x+1,y+1).
On the rectangle map from (0,0) to (109,109), there are several villages scattering on the map. Villagers will do business deals with salesmen from northwestern, but not northern or western. In mathematical language, this means when there is a village k on (xk,yk) (1≤xk≤109,1≤yk≤109), only the one who was from (xk−1,yk−1) to (xk,yk) will be able to earn vk dollars.(YJJ may get different number of dollars from different village.)
YJJ has no time to plan the path, can you help him to find maximum of dollars YJJ can get.

Input

The first line of the input contains an integer T (1≤T≤10),which is the number of test cases.

In each case, the first line of the input contains an integer N (1≤N≤105).The following N lines, the k-th line contains 3 integers, xk,yk,vk (0≤vk≤103), which indicate that there is a village on (xk,yk) and he can get vk dollars in that village.
The positions of each village is distinct.

Output

The maximum of dollars YJJ can get.

Sample Input

1 3 1 1 1 1 2 2 3 3 1

Sample Output

3

Source

2018中国大学生程序设计竞赛 - 网络选拔赛

代码

unique知识点https://www.cnblogs.com/hua-dong/p/7943983.html

代码来源https://blog.csdn.net/sizaif/article/details/82054704

#include<bits/stdc++.h>//#include<bits/stdc++.h>包含了目前C++所包含的所有头文件。它包含了以下头文件(C++):
#include<stdio.h>

typedef long long ll;//类型的别名

const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
using namespace std;

int n;
int tree[maxn],a[maxn],ans;//树状数组   和结果储存变量

struct node{//抽象化节点 
	int x,y,val;
	int id;
}p[maxn];

void add(int k,int num){
	while(k<maxn){
		tree[k]=max(num,tree[k]);
		ans=max(ans,tree[k]);//更新ans的值 
		k+=k&(-k);
	}
}
int Qmax(int k){//询问1到k中的最大值 
	int res=0;
	while(k) {
		res=max(tree[k],res);
		k-=k&(-k);
	}
	return res;
}

bool cmp(node a,node b){
	return (a.x<b.x)||(a.x==b.x&&a.y>b.y);//y变量是从大到小排序,x是从小到大排序 
} 

 
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		memset(tree,0,sizeof(tree));//初始化树形数组 
		memset(p,0,sizeof(p));//初始化节点信息 
		memset(a,0,sizeof(a));//初始化数组a
		ans=0;
		scanf("%d",&n); 
		for(int i=1;i<=n;i++){
			scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].val);
			a[i]=p[i].y;//欲对y进行离散化 
		}
		sort(a+1,a+n+1);
		int size=unique(a+1,a+n+1)-(a+1);//获取去重之后的大小,用来对y离散化
		for(int i=1;i<=n;i++){
			p[i].y=lower_bound(a+1,a+size+1,p[i].y)-(a+1)+1;//获取y在去重且排序好的数组的位置
												//即对y的离散化
		} 
		sort(p+1,p+n+1,cmp) ;//对节点进行排序 
		for(int i=1;i<=n;i++){
			ll val=Qmax(p[i].y-1)+p[i].val;
			add(p[i].y,val); 
		}
		printf("%d\n",ans);		 
		
		
	}
	
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_36160277/article/details/82144180