• Bzoj 1537: [POI2005]Aut- The Bus 题解 [由暴力到正解]


    1537: [POI2005]Aut- The Bus

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 387  Solved: 264
    [Submit][Status][Discuss]

    Description

    Byte City 的街道形成了一个标准的棋盘网络 – 他们要么是北南走向要么就是西东走向. 北南走向的路口从 1 到 n编号, 西东走向的路从1 到 m编号. 每个路口用两个数(i, j) 表示(1 <= i <= n, 1 <= j <= m). Byte City里有一条公交线, 在某一些路口设置了公交站点. 公交车从 (1, 1) 发车, 在(n, m)结束.公交车只能往北或往东走. 现在有一些乘客在某些站点等车. 公交车司机希望在路线中能接到尽量多的乘客.帮他想想怎么才能接到最多的乘客.

    Input

    第一行三个数n, m 和 k – 表示北南走向的路的个数以及西东走向的路和乘客等车的站点的个数. ( 1 <= n <= 10^9, 1 <= m <= 10^9, 1 <= k <= 10^5). 接下来k 行每行描述一个公交站的信息.第 i + 1 行三个正整数 xi, yi 和 pi, 1 <= xi <= n, 1 <= yi <= m, 1 <= pi <= 10^6. 表示在(xi, yi) 有 pi 个乘客在等车. 每个路口在数据中最多出现一次,乘客总数不会超过1 000 000 000.

    Output

    一个数表示最多能接到的乘客数量.

    Sample Input

    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

    Sample Output

    11
     
      这道题本身不是太难,只是因为是一道可以从暴力直接分析到正解的典型题目所以记录一下。
     
      这道题n*m暴力还是比较容易相出来的,反正一个点只能从左侧或上方转移过来,我们只要打一个DP就行了,但对于10^18的数据正解不会是这个。
      我们可以注意到,真正对于答案有贡献的只有车站,对于一些无车站的点对于答案毫无贡献,而k自己本身也不是很大,我们能不能通过车站之间的位置关系来得到答案呢?当然可以。我们可以观察到,对于一个点只有横纵坐标都不大于它的点才能对他有贡献,我们只要把所有点排一边序,然后利用树状数组进行转移答案就出来了。
     1 #pragma GCC optimze("O3")
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<queue>
     7 #include<algorithm>
     8 #include<cmath>
     9 #include<map>
    10 #define N 100005
    11 using namespace std;
    12 int f[N],n,m,t,zz,jg[N];
    13 struct no
    14 {
    15     int x,y,data;
    16 }node[N];
    17 map<int,int> ls;
    18 bool px(no a,no b)
    19 {
    20     if(a.x==b.x)return a.y<b.y;
    21     return a.x<b.x;
    22 }
    23 int a[N];
    24 int lowbit(int x)
    25 {
    26     return x&(-x);
    27 }
    28 void add(int x,int z)
    29 {
    30     for(int i=x;i<=m;i+=lowbit(i))
    31         a[i]=max(a[i],z);
    32 }
    33 int get(int x)
    34 {
    35     int ans=0;
    36     for(int i=x;i>0;i-=lowbit(i))
    37         ans=max(ans,a[i]);
    38     return ans;
    39 }
    40 int main()
    41 {
    42     scanf("%d%d%d",&n,&m,&t);
    43     for(int i=1;i<=t;i++)
    44     {
    45         scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].data);
    46         if(!ls[node[i].y])
    47         {
    48             zz++;
    49             ls[node[i].y]=1;
    50             jg[zz]=node[i].y;
    51         }
    52     }
    53     sort(node+1,node+t+1,px);
    54     sort(jg+1,jg+zz+1);
    55     for(int i=1;i<=zz;i++)
    56         ls[jg[i]]=i;
    57     m=zz;
    58     for(int i=1;i<=t;i++)
    59         node[i].y=ls[node[i].y];
    60     int ans=0;
    61     for(int i=1;i<=t;i++)
    62     {
    63         f[i]=get(node[i].y)+node[i].data;
    64         add(node[i].y,f[i]);
    65     }
    66     printf("%d
    ",get(m));
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    google glog 使用方法
    LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
    c++ ‘nullptr’ 在此作用域中尚未声明
    Impala 使用的端口
    忽略“Signal: SIGSEGV (Segmentation fault)”
    查看python脚本的运行pid,让python脚本后台运行
    阿里云主机运行速度慢的解决办法
    在Git.oschina.net中配置TortoiseGit使用sshkey,无需输入账号和密码
    抓取国家的学校编码数据
    CAS统一登录认证好文汇集贴
  • 原文地址:https://www.cnblogs.com/liutianrui/p/7588520.html
Copyright © 2020-2023  润新知