1. 程式人生 > >Bzoj 1537: [POI2005]Aut- The Bus 題解 [由暴力到正解]

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

通過 所有 data php pla def urn fin geo

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\n",get(m));
67     return 0;
68 }
View Code

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