YJJ's Salesman

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

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
 
数据范围太大,一开始要对数据进行离散化
一开始没做过离散化的题  ,就是把几个有大小顺序的数(很大)用一些小的数来记录排序
比如1,10000,10000000000排序和离散化后1,2,3排序是没啥区别的
接下来用线段树维护区间的最大值
是类似于01背包的求出最大值
具体看代码吧
#include<bits/stdc++.h>
#define lson l,m,k<<1
#define rson m+1,r,k<<1|1
using namespace std;
#define maxn 200010
int tree[maxn<<];
void pushup(int k)
{
tree[k]=max(tree[k<<],tree[k<<|]);
}
void build(int l,int r,int k)
{
if(l==r)
{
tree[k]=;
return;
}
int m=(l+r)>>;
build(lson);
build(rson);
pushup(k);
}
int query_getmax(int x,int y,int l,int r,int k)//这里是求出最大值
{
if(x<=l&&r<=y)
return tree[k];
int m=(l+r)>>;
int ans=;
if(x<=m) ans=max(ans,query_getmax(x,y,lson));
if(y>m) ans=max(ans,query_getmax(x,y,rson));
return ans;
}
void update(int p,int c,int l,int r,int k)
{
if(l==r)
{
tree[k]=c;
return;
}
int m=(l+r)>>;
if(p<=m) update(p,c,lson);
else update(p,c,rson);
pushup(k);
}
struct point{
int x,y,w;
int ha_x,ha_y;//记录离散后的坐标
}a[];
bool cmp1(point a,point b)
{
return a.x<b.x;
}
bool cmp2(point a,point b)
{
return a.y<b.y;
}
bool cmp3(point a,point b)
{
if(a.x==b.x) return a.y>b.y;
return a.x<b.x;
}
int main()
{
int n,m;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int ha=;
build(,n,);
for(int i=;i<=n;i++)
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w);
sort(a+,a++n,cmp1);
int haxx=;
for(int i=;i<=n;i++)//对x坐标得点进行离散化
{
a[i].ha_x=haxx;
if(a[i+].x!=a[i].x)haxx++;
}
int hayy=;
sort(a+,a++n,cmp2);
for(int i=;i<=n;i++)//对y坐标进行离散化
{
a[i].ha_y=hayy;
if(a[i+].y!=a[i].y)hayy++;
}
sort(a+,a++n,cmp3);
haxx--,hayy--;
for(int i=;i<=n;i++)//跟一维01背包的更新可像
{
if(a[i].ha_y==) update(a[i].ha_y,a[i].w,,n,);//到了最下面,在1的线段树出更新
else
{
int t=query_getmax(,a[i].ha_y-,,n,)+a[i].w;//从1到a[i].ha_y 这个区间求出最大值
update(a[i].ha_y,t,,n,);//把这个点的最优值储存在a[i].ha_y上
}
}
cout<<query_getmax(,n,,n,)<<endl;
}
return ;
}
 

hdu6447的更多相关文章

  1. hdu6447 YJJ's Salesman

    这个题意和数据范围一看就是离散化之后树状数组优化DP.给的"从左下方走上去才能拿到收益"的性质其实可以当成"必须从横纵坐标严格比某个点小的地方转移过来".1A了 ...

  2. HDU6447 网络赛 YJJ's Salesman(DP + 线段树)题解

    思路:若用dp[i][j]表示走到(i,j)的最大值,那么dp[i][j] = max(dp[i - 1][j],dp[i][j - 1],dp[i - 1][j - 1] + v),显然O(n^2) ...

  3. HDU6447(离散化扫描线+树状数组)

    一眼看过去就x排序扫描一下,y是1e9的离散化一下,每层用树状数组维护一下,然后像dp倒着循环似的树状数组就用y倒着插就可行了. 类似题目练习:BZOJ4653.BZOJ1218 #pragma co ...

  4. HDU6447 YJJ's Salesman-2018CCPC网络赛-线段树求区间最值+离散化+dp

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门  原题目描述在最下面.  1e5个点,问 ...

随机推荐

  1. Java 今天是否为节假日

    /** * 测试今天是不是节假日 * 创建日期:2017年8月30日上午10:00:41 * 修改日期: * 作者:zhangsp * TODO * return */ public void wor ...

  2. 404 Note Found队-现场编程

    目录 组员职责分工 github 的提交日志截图 程序运行截图 程序运行环境 GUI界面 基础功能实现 运行视频 LCG算法 过滤(降权)算法 算法思路 红黑树 附加功能一 背景 实现 附加功能二(迭 ...

  3. 杂记(那些我还容易混淆的c和c++知识)

    1: 定义一个对象时先调用基类的构造函数.然后调用派生类的构造函数:析构的时候恰好相反:先调用派生类的析构函数.然后调用基类的析构函数.2:  多态性具体体现在运行和编译两个方面:在程序运行时的多态性 ...

  4. sharepoint rest 脚本发送邮件

    function processSendEmails() { var from = 'asad@Example.com', to = 'someone@Example.com', body = 'He ...

  5. 【Dubbo源码阅读系列】服务暴露之远程暴露

    引言 什么叫 远程暴露 ?试着想象着这么一种场景:假设我们新增了一台服务器 A,专门用于发送短信提示给指定用户.那么问题来了,我们的 Message 服务上线之后,应该如何告知调用方服务器,服务器 A ...

  6. CSP 试题编号201803-2 Java实现

    package HB; import java.util.Scanner; public class Test_06 { public static void main(String[] args) ...

  7. Docker 常用命令——镜像

    Docker 常用命令 帮助命令 docker version    --版本信息 docker info       --详细信息 docker --help     --帮助 镜像命令 1.doc ...

  8. GCD 多线程技术

    Grand Central Dispatch(GCD)是异步执行任务的技术之一.一般将应用程序中记述的线程管理用 的代码在系统级中实现.开发者只需要定义想执行的任务并追加到适当的Dispatch Qu ...

  9. (转载)SendKeys.Send()的使用

    SendKeys.Send() 使用SendKeys将键击和组合键击发送到活动应用程序.此类无法实例化.若要发送一个键击给某个类并立即继续程序流,请使用Send.若要等待键击启动的任何进程,请使用Se ...

  10. Delphi XE7调用Java Class,JAR

    Delphi XE5,XE6需要用户手工编译并将Classes.Dex加入到包中,不过Delphi XE7可以省掉这些工作了. 如何在XE7中调用Java,具体步骤如下: 1.将jar文件添加到XE7 ...