• 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
  • 相关阅读:
    区间dp_学习笔记
    状态压缩dp_学习笔记
    第十一届蓝桥杯C/C++ J题网络分析(带权并查集水题)
    状态机dp学习笔记_AcWing
    洛谷P4052 [JSOI2007]文本生成器(AC自动机+DP)
    洛谷P5840 [COCI2015]Divljak (AC自动机+fail树上dfs序+树上差分线段树维护)
    洛谷P3401 [USACO12JAN]Video Game G(AC自动机+记忆化搜索)
    HDU3613 Best Reward (exKMP/manacher)
    洛谷P2375 [NOI2014]动物园(KMP+倍增优化)
    ICPC2017南宁站题解(A,E,F,H,I,J,L,M)
  • 原文地址:https://www.cnblogs.com/liutianrui/p/7588520.html
Copyright © 2020-2023  润新知