HDU6447 YJJ's Salesman 2018中国大学生程序设计竞赛 - 网络选拔赛1010 离散化+线段树+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中国大学生程序设计竞赛 - 网络选拔赛

第一反应是最短路,但是没法建图而且会TLE。场上一直在想怎么DP,无奈实在点数太多不会处理,也没做过这种二维最长上升序列。

队友临结束还有三分钟离散化+线段树AC....菜鸡默默补题

题解:

DP思路很容易想到:dp[i][j] = max{dp[i-1][j],dp[i][j-1],dp[i-1][j-1]+v[i][j]},但是O(n^2)的dp肯定会T,显然最大值肯定会在村庄处取得,所以可以离散化减少点数,其次因为人只能向右或向下或向右下移动,所以可以从左往右,从上到下更新,若用f[j]表示走到第j列所能取得的最大值,则走到第i行第j列的f[j] = max{f[j],max(f[j-1])+v[i][j]},本题先离散化用线段树维护前k列的最值,然后按行从小到大dp即可。

 1 #include <bits/stdc++.h>
 2 #define mid ((tr[d].l + tr[d].r)>>1)
 3 #define lc (d << 1)
 4 #define rc (d << 1|1)
 5 using namespace std;
 6 const int maxn = 1e5+5;
 7 struct Tr{
 8     int l,r,mx;
 9 }tr[maxn*4];
10 struct Node{
11     int x,y,w;
12     bool operator < (const Node &a)const{
13         //?????
14         return (x == a.x) ? y > a.y : x < a.x;
15     }
16 }node[maxn];
17 int T,n;
18 int hash_x[maxn],hash_y[maxn];
19 int n1,n2;
20
21 void build(int d,int l,int r){
22     tr[d].l = l,tr[d].r = r,tr[d].mx = 0;
23     if (tr[d].l == tr[d].r){
24         return;
25     }
26     build(lc,l,mid); build(rc,mid+1,r);
27 }
28
29 int query(int d,int l,int r){
30     if (tr[d].l == l && tr[d].r == r){
31         return tr[d].mx;
32     }
33     if (mid >= r) return query(lc,l,r);
34     else if (mid < l) return (rc,l,r);
35     else return max(query(lc,l,mid),query(rc,mid+1,r));
36 }
37
38 void update(int d,int pos,int w){
39     if (tr[d].l == tr[d].r && tr[d].r == pos) {
40         tr[d].mx = max(w,tr[d].mx);
41         return;
42     }
43     if (mid >= pos) update(lc,pos,w);
44     else update(rc,pos,w);
45     tr[d].mx = max(tr[lc].mx,tr[rc].mx);
46 }
47
48 int main(){
49     scanf("%d",&T);
50     while(T--){
51         scanf("%d",&n);
52         for (int i = 0;i < n;++i){
53             scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].w);
54             hash_x[i] = node[i].x,hash_y[i] = node[i].y;
55         }
56         sort(hash_x,hash_x+n);
57         sort(hash_y,hash_y+n);
58         n1 = unique(hash_x,hash_x+n) - hash_x;
59         n2 = unique(hash_y,hash_y+n) - hash_y;
60         for (int i = 0;i < n;++i){
61             node[i].x = lower_bound(hash_x,hash_x+n1,node[i].x) - hash_x;
62             node[i].y = lower_bound(hash_y,hash_y+n2,node[i].y) - hash_y;
63         }
64         sort(node,node+n);
65         build(1,0,n);
66         int ans = 0;
67         for (int i = 0;i < n;++i){
68             int tmp;
69             if (node[i].y == 0) tmp = node[i].w;
70                 else tmp = query(1,0,node[i].y-1) + node[i].w;
71             update(1,node[i].y,tmp);
72             ans = max(ans,tmp);
73         }
74         printf("%d\n",ans);
75     }
76     return 0;
77 }

HDU6447 YJJ's Salesman 2018中国大学生程序设计竞赛 - 网络选拔赛1010 离散化+线段树+DP

原文地址:https://www.cnblogs.com/mizersy/p/9535259.html

时间: 2024-10-10 01:27:10

HDU6447 YJJ's Salesman 2018中国大学生程序设计竞赛 - 网络选拔赛1010 离散化+线段树+DP的相关文章

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

[HDU 6447][YJJ&#39;s Salesman][2018CCPC网络选拔赛 1010][离散化+线段树+DP]

链接: http://acm.hdu.edu.cn/showproblem.php?pid=6447 题意: 左上角(0,0),右下角(10^9,10^9)的网格,其中有n(1<=n<=10^5)个方格内有权值. 一次只能沿右,下,右下三个方向走一个格子,只有沿右下方向走到格子里才可以获得权值. 问从(0,0)到(10^9,10^9)的路径最大权值是多少. 思路: 网格路径权值问题,第一感考虑DP,x从上往下,y从左往右刷表,状态转移方程为dp[i][j]=max(dp[i-1][j],dp[

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

传送门 A.HDU6438 Buy and Resell 题意 给你N天N个价格,每天都可以从1.买入一个,2.卖出一个,3.什么都不做,求最高获利 低买高卖问题,这题与其他的差距就是要在满足获利最多的情况下,买卖次数最小; 思路 手算一下发现价格具有传递性;例如数据是1,5,9; 5的时候买入1赚了4;9的时候买入5赚了4;相当于直接把5当成跳板直接9的时候买1;然后再把中间的5当成没有买过的; 建立一个小根堆(优先队列);把当前遇到的天数的价钱放入,然后对于第i天; 1.如果新天数的价钱比堆

2018中国大学生程序设计竞赛 - 网络选拔赛 hdu6438 Buy and Resell 买入卖出问题 贪心

Buy and Resell Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1126    Accepted Submission(s): 359 Problem Description The Power Cube is used as a stash of Exotic Power. There are n cities numbe

2018中国大学生程序设计竞赛 - 网络选拔赛 Dream hdu6440 Dream 给出一个(流氓)构造法

http://acm.hdu.edu.cn/showproblem.php?pid=6440 题意:让你重新定义任意一对数的乘法和加法结果(输出乘法口诀表和加法口诀表),使得m^p+n^p==(m+n)^p(p为质数),并且存在一个0<q<p使得 q^k(0<k<p)取遍1~p-1的所有值,并且该运算是封闭的(exists an integer q(0<q<p) to make the set {qk|0<k<p,k∈Z} equal to {k|0<

2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6154 CaoHaha&#39;s staff 思维

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6154 题意:在笛卡尔坐标系下,画一个面积至少为  n 的简单多边形,每次只能画一条边或者一个格子的对角线,问至少要画几条. 解法:如果一个斜着的矩形长宽分别是 a,b,那么它的面积是 2ab.最优解肯定是离 sqrt(n/2)很近的位置.想想 n=5 时答案为什么是7 然后在那个小范围内枚举一下就好了.我给一张做题时画的图 #include <bits/stdc++.h> using namesp

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

solved 4/11 2016中国大学生程序设计竞赛 - 网络选拔赛

HDU 5833 Zhu and 772002(高斯消元)——2016中国大学生程序设计竞赛 - 网络选拔赛

传送门 Zhu and 772002 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 48    Accepted Submission(s): 16 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test the abili

HDU 5832 A water problem(取模~)—— 2016中国大学生程序设计竞赛 - 网络选拔赛

传送门 A water problem Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 60    Accepted Submission(s): 37 Problem Description Two planets named Haha and Xixi in the universe and they were created wit