码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-08-26 01:24:04      阅读:870      评论:0      收藏:0      [点我收藏+]

标签:font   space   def   query   using   oid   ons   for   区间   

目录

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

Catalog

Problem:Portal传送门

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

Solution:

技术分享图片
?十分详细了。
?直接线段树区间最值。当然也可以树状数组,不能st表。
?\(dp[i] = max(query\_max(0,dp[i]-1,1)+val[i] ,dp[i])\)
?\(update(i, dp[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:

技术分享图片

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

标签:font   space   def   query   using   oid   ons   for   区间   

原文地址:https://www.cnblogs.com/Cwolf9/p/9535914.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!