zoukankan      html  css  js  c++  java
  • RQNOJ Bus

    H城是一座小城市,前几日才刚刚建立公交系统,且只有一辆公交车。于是,如何最大化这唯一一辆公交车的载客量成了亟待解决的问题。

    H城的俯视图可以近似地看成是一个棋盘网络——共有N行M列,从南向北,每行从1到M标号,从西向东,每列从1到N标号。经实地考察,公交总公司选定了K个可以设为站点的地方,其中第K个站点位于第Xi列,第Yi行,预计每天有Pi名乘客需要在此乘车。

    设有序数对(X,Y)表示第X列,第Y行。每天,公交车从(1,1)开出,驶向(N,M),途中只能向北或向东行驶。

    现在,公交总公司希望你能够帮助他们选定一条路线,使得能够接到的乘客数最大,我们假设公交车的容量无限大。

    输入格式

    一个非负整数ans,表示最多能接到的乘客数。

    输出格式

    若干行,对于每个询问输出’Yes’表示他们是亲戚,或’No’表示他们不是亲戚

    样例输入

    8 7 11
    4 3 4
    6 2 4
    2 3 2
    5 6 1
    2 5 2
    1 5 5
    2 1 1
    3 1 1
    7 7 1
    7 4 2
    8 6 2

    样例输出

    11

     
    注释

    如果把每个点看成一个状态,F[x,y]表示最大人数,那么它只能从它下面或者左边的点转移过来,于是每次就是找到一个x,y都小于等于该点的最大的F[X,Y]。这实际上是一个加权LIS,但是权值和坐标值都很大,于是想到用分治代替平衡树的方法来维护。

    我们先给x排序离散好,这里要满足x相等的点y小的在前面。然后把y快排好,进入分治。

    对于每次分治[l,r],我们的任务是用[l,mid]的F去更新[mid+1,r]的F(因为右半边的F值只受左半边的影响,大概类似NOI Cash那个题)。由于我们已经排好了y,那么分治的下标其实就是x,于是对于每个[l,r]过程,我们要把它按照x相对mid的大小分成两个部分[l,mid],[mid+1,r],这两部分分别是y单增的。

    然后,左半边[l,mid]维护一个y和F都单调增的数组,然后扫一遍右半边[mid+1,r],找到不小于这个点y值得最靠右的一个F(也就是最大的F),转移即可。

    更新完F值,我们需要把分开的两部分合并起来,也就是归并排序,保证回溯到上一层的时候[l,r]仍然是y单增的。

    需要注意的是,由于每次要拆了又合,所以F的下标很乱,不如直接把F记到每个点上,这样随着分治的过程,F值会始终跟着这个点分来分去。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #define maxn 102000
     7 using namespace std;
     8 
     9 struct point
    10 {
    11     int x,y,v,f;
    12 }p[maxn],q[maxn],stack[maxn];
    13 int f[maxn];
    14 int nx,ny,n,ans;
    15 
    16 void solve(int l,int r)
    17 {
    18     if (l==r){
    19         if (p[l].f==0) p[l].f=p[l].v;
    20         ans=max(ans,p[l].f);
    21         return ;
    22     }
    23     int mid=(l+r)>>1;
    24     int l1=l,l2=mid+1;
    25     for (int i=l;i<=r;i++) if (p[i].x<=mid) q[l1++]=p[i]; else q[l2++]=p[i];
    26     for (int i=l;i<=r;i++) p[i]=q[i];
    27     solve(l,mid);
    28     int top=0;
    29     for (int i=l;i<=mid;i++){
    30         if (p[i].f>stack[top].f) stack[++top]=p[i];
    31     }
    32     int now=0;
    33     for (int i=mid+1;i<=r;i++){
    34         while (now<top&&stack[now+1].y<=p[i].y) now++;
    35         if (now) p[i].f=max(p[i].f,stack[now].f+p[i].v);
    36     }
    37     solve(mid+1,r);
    38     l1=l,l2=mid+1;
    39     for (int i=l;i<=r;i++) 
    40         if ((p[l1].y<=p[l2].y||l2>r)&&l1<=mid) q[i]=p[l1++]; else q[i]=p[l2++];
    41     for (int i=l;i<=r;i++) p[i]=q[i];
    42 }
    43     
    44 bool cmp1(point a,point b)
    45 {
    46     return (a.x<b.x)||(a.x==b.x&&a.y<b.y);
    47 }
    48 bool cmp2(point a,point b)
    49 {
    50     return a.y<b.y;
    51 }
    52 
    53 int main()
    54 {
    55     freopen("bus.in","r",stdin);
    56     freopen("bus.out","w",stdout);
    57     scanf("%d%d%d",&nx,&ny,&n);
    58     for (int i=1;i<=n;i++)
    59         scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].v);
    60     sort(p+1,p+n+1,cmp1);
    61     for (int i=1;i<=n;i++) p[i].x=i;
    62     sort(p+1,p+n+1,cmp2);
    63     solve(1,n);
    64     printf("%d
    ",ans);
    65     return 0;
    66 }
    Bus

     

  • 相关阅读:
    hugo搭建个人博客
    docker安装mongo
    java+vue跨域每次请求获取不同session问题
    优雅的使用JdbcTemplate
    docker布署springcloud无法使用feign通信
    xxl-job不兼容graylog解决方案
    Springboot集成graylog
    Springboot集成swagger和knife
    Springboot集成xxl-Job
    Springboot中redisTemplate乱码或json转换问题
  • 原文地址:https://www.cnblogs.com/zig-zag/p/3412890.html
Copyright © 2011-2022 走看看