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

版权声明:转载请说明,欢迎交流! https://blog.csdn.net/qq_39599067/article/details/82056746

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

Catalog

Problem:Portal传送门

 原题目描述在最下面。
 1e5个点,问从(0,0)走到(1e9,1e9)的最大收益。
 当你从(u-1,v-1)走到(u,v)时,你可以获得点(u,v)的权值。

Solution:

这里写图片描述
 十分详细了。
 直接线段树区间最值。当然也可以树状数组,不能st表。
d p [ i ] = m a x ( q u e r y _ m a x ( 0 , d p [ i ] 1 , 1 ) + v a l [ i ] , d p [ i ] )
u p d a t e ( i , d p [ i ] , 1 )
 记得离散化再排序,先x从小到大,再y从大到小,每次更行一行。
 按01背包的更新顺序,滚动数组优化为一维。
 细节见代码。

AC_Code:

#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
#define mme(a,b) memset((a),(b),sizeof((a))) 
using namespace std;
typedef unsigned long long LL;
const int N = 2e5 + 7;
const int M = 1e5 + 7;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int ar[N],br[N];//离散化
int dp[N];
struct lh{//储存1e5个点
  int x,y,v;
}op[N];
bool cmp(lh &a,lh &b){
  if(a.x!=b.x)return a.x<b.x;
  return a.y>b.y;
}
int n;
/**********线段树区间最值**********/
struct lp{
  int l, r, sum;
}cw[N<<2];
void push_up(int rt){
  cw[rt].sum = max(cw[lson].sum, cw[rson].sum);
}
void build(int l,int r,int rt){
  cw[rt].l = l;cw[rt].r = r;cw[rt].sum = 0;
  if(l==r){
    return;
  }
  int mid = (l+r)/2;
  build(l,mid,lson);build(mid+1,r,rson);
  push_up(rt);
}
void update(int p,int c,int rt){
  int l = cw[rt].l, r = cw[rt].r,mid = (l+r)/2;
  if(l==r){
    cw[rt].sum = c;
    return;
  }
  if(p<=mid)update(p,c,lson);
  else update(p,c,rson);
  push_up(rt);
}
int query(int L,int R,int rt){
  int l = cw[rt].l, r = cw[rt].r,mid = (l+r)/2;
  if(L<=l&&r<=R){
    return cw[rt].sum;
  } 
  if(L>mid)return query(L,R,rson);
  else if(R<=mid)return query(L,R,lson);
  return max(query(L,mid,lson),query(mid+1,R,rson)); 
}
/****************/
int main(){
  int tim;
  scanf("%d", &tim);
  while(tim--){
    scanf("%d", &n);
    for(int i = 0; i < n; ++i){
      scanf("%d%d%d",&op[i].x,&op[i].y,&op[i].v);
      ar[i] = op[i].x;br[i]=op[i].y;
    }
    int p = n + 1;
    ar[n] = 0;br[n] = 0;
    sort(ar,ar+p);
    sort(br,br+p);
    int a = unique(ar,ar+p)-ar;
    int b = unique(br,br+p)-br;
    for(int i = 0; i < n; ++i){
      op[i].x=lower_bound(ar,ar+a,op[i].x)-ar;
      op[i].y=lower_bound(br,br+b,op[i].y)-br;
    }
    //以上离散化
    sort(op,op+n,cmp);
    build(0, b, 1);
    mme(dp, 0);
    for(int i = 0; i < n; ++i){
      int flag = op[i].x, j;
      for(j = i; j < n; ++j){
        if(op[j].x != flag){
          break;
        }
        int tmp = query(0, op[j].y-1, 1) + op[j].v;
        if(tmp > dp[op[j].y]){
          dp[op[j].y] = tmp;
          update(op[j].y, dp[op[j].y], 1);
        }
      }
      i = j - 1;
    }
    int ans = 0;
    for(int i = 0; i <= b; ++i){
      ans = max(ans, dp[i]);
    }
    printf("%d\n", ans);
  }
  return 0;
}


Problem Description:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/82056746
今日推荐