题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6447
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. Input The first line of the input contains an integer T (1≤T≤10) ,which is the number of test cases. Output The maximum of dollars YJJ can get. Sample Input 1 3 1 1 1 1 2 2 3 3 1 Sample Output 3 |
题目大意:在一个10^9*10^9的地图上,分布着10^5个村庄,一个人从0,0,处出发,前往10^9,10^9处,中间经过村庄可以获得村庄的宝藏,但是只有从村庄(x,y)的(x-1,y-1)坐标进入村庄才会获得宝藏,输出一个人从起点到终点能够获得的最多的宝藏;
一开始想的是DP,但是一看10^9的地图.....直接放弃,虽然想到离散化,但是不知道怎么离散化,结果到比赛结束也没有写出来..好菜,按照坐标离散化,之后建一个01dp;
状态转移方程:dp[x]=max(dp[x-1],dp[x]);用上线段树去维护这个dp
ac:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
//#define mod 1e9+7
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
const int MAXN=2e5+10;
const ll mod=1e9+7;
struct dot{
int x,y;
ll v;
}dots[MAXN];
ll tree[MAXN<<2];
ll dp[MAXN];
int num[MAXN];
int n;
void intt()
{
clean(dp,0);
clean(tree,0);
clean(num,0);
}
bool cmp1(dot a,dot b)
{
return a.x<b.x;
}
bool cmp2(dot a,dot b)
{
return a.y<b.y;
}
void updata(int L,ll x,int l,int r,int rt)
{
if(l==r)
{
tree[rt]=max(x,tree[rt]);
return ;
}
int mid=(l+r)>>1;
if(L<=mid)
updata(L,x,l,mid,rt<<1);
else
updata(L,x,mid+1,r,rt<<1|1);
tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
ll Query(int L,int R,int l,int r,int rt)
{
if(l>=L&&r<=R)
return tree[rt];
int mid=(l+r)>>1;
ll ans=0;
if(L<=mid)
ans=max(ans,Query(L,R,l,mid,rt<<1));
if(R>mid)
ans=max(ans,Query(L,R,mid+1,r,rt<<1|1));
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
intt();
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d%d%lld",&dots[i].x,&dots[i].y,&dots[i].v);
sort(dots+1,dots+n+1,cmp1);
int temp=dots[1].x,id=1;//离散x
dots[1].x=id;
for(int i=2;i<=n;++i)
{
if(dots[i].x==temp)
dots[i].x=id;
else
{
temp=dots[i].x;
dots[i].x=++id;
}
}
sort(dots+1,dots+1+n,cmp2);
temp=dots[1].y,id=1;//离散y
dots[1].y=id;
num[id]=1;
for(int i=2;i<=n;++i)
{
if(dots[i].y==temp)
dots[i].y=id;
else
{
temp=dots[i].y;
dots[i].y=++id;
}
num[id]++;
}
//离散化正确
id=0;
int x,y;
ll v;
for(int i=1;i<=n;++i)//便利n个y
{
for(int j=1;j<=num[i];++j)
{
int k=j+id;
x=dots[k].x,y=dots[k].y,v=dots[k].v;
if(x==1)//该位置的x是1,之前没有东西
dp[x]=v;
else
{
ll ans1=Query(1,x-1,1,n,1)+v;
ll ans2=Query(1,x,1,n,1);
//cout<<ans1<<" "<<ans2<<endl;
dp[x]=max(ans1,ans2);
}
}
for(int j=1;j<=num[i];++j)
{
int k=j+id;
x=dots[k].x,y=dots[k].y,v=dots[k].v;
updata(x,dp[x],1,n,1);//将该位置的dp值放入数组
}
// for(int j=1;j<=n<<2;++j)
// cout<<tree[j]<<" ";
// cout<<endl;
// for(int j=1;j<=n;++j)
// cout<<dp[j]<<" ";
// cout<<endl;
id=id+num[i];
}
// for(int i=1;i<=n<<2;++i)
// cout<<tree[i]<<endl;
printf("%lld\n",tree[1]);
}
}