The streets of Byte City form a regular, chessboardlike network - they are either north-south or west-east directed. We shall call them NS- and WE-streets. Furthermore, each street crosses the whole city. Every NS-street intersects every WE- one and vice versa. The NS-streets are numbered from \(1\) to \(n\), starting from the westernmost. The WE-streets are numbered from \(1\) to \(m\), beginning with the southernmost. Each intersection of the \(i\)'th NS-street with the \(j\)'th WE-street is denoted by a pair of numbers \((i,j)\) (for \(1\le i\le n\), \(1\le j\le m\)).ios
There is a bus line in Byte City, with intersections serving as bus stops. The bus begins its itinerary by the \((1,1)\) intersection, and finishes by the \((n,m)\) intersection. Moreover, the bus may only travel in the eastern and/or northern direction.c++
There are passengers awaiting the bus by some of the intersections. The bus driver wants to choose his route in a way that allows him to take as many of them as possible. (We shall make an assumption that the interior of the bus is spacious enough to take all of the awaiting passengers, regardless of the route chosen.)TaskWrite a programme which:數組
reads from the standard input a description of the road network and the number of passengers waiting at each intersection,finds, how many passengers the bus can take at the most,writes the outcome to the standard output.網絡
Byte City 的街道造成了一個標準的棋盤網絡 – 他們要麼是北南走向要麼就是西東走向. 北南走向的路口從 1 到 n編號, 西東走向的路從1 到 m編號. 每一個路口用兩個數(i, j) 表示(1 <= i <= n, 1 <= j <= m). Byte City裏有一條公交線, 在某一些路口設置了公交站點. 公交車從 (1, 1) 發車, 在(n, m)結束.公交車只能往北或往東走. 如今有一些乘客在某些站點等車. 公交車司機但願在路線中能接到儘可能多的乘客.幫他想一想怎麼才能接到最多的乘客.less
The first line of the standard input contains three positive integers \(n\), \(m\) and \(k\) - denoting the number of NS-streets, the number of WE-streets and the number of intersections by which the passengers await the bus, respectively \((1\le n\le 10^9, 1\le m\le 10^9, 1\le k\le 10^5)\).this
The following \(k\) lines describe the deployment of passengers awaiting the bus, a single line per intersection. In the \((i+1)\)'st line there are three positive integers \(x_i, y_i\) and \(p_i\), separated by single spaces, \(1\le x_i\le n,1\le y_i\le m,1\le p_i\le 10^6\) . A triplet of this form signifies that by the intersection\((x_i,y_i)p_i\) passengers await the bus. Each intersection is described in the input data once at the most. The total number of passengers waiting for the bus does not exceed \(1\ 000\ 000\ 000\).spa
Your programme should write to the standard output one line containing a single integer - the greatest number of passengers the bus can take.code
輸入orm
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
首先想到的是一個\(n\times m\)的DP,可是由於\(n,m\)均爲\(10^9\),因此確定是不行的
能夠注意到,雖然\(n,m\)很大,可是點的個數卻不多,只有\(10^5\)個,因此能夠考慮將點先離散化,這樣時間就從\(O(n\times m)降到了O(k^2)\),可是依舊會超時
這時,咱們能夠將每一個點按橫座標升序,若是橫座標相同,縱座標升序的順序排序,而後進行DP
狀態轉移方程:\(dp[i]=max(dp[1],dp[2]...dp[i])+p[i]\)對於\(max(dp[i])\),能夠用樹狀數組來求
#include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define ms(a,b) memset(a,b,sizeof(a)) const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const int maxn=2e6+10; const int mod=1e9+7; const int maxm=1e3+10; using namespace std; struct wzy { int x,y,s; }p[maxn]; int c[maxn]; int mapx[maxn],mapy[maxn]; bool cmp(wzy u,wzy v) { if(u.x==v.x) return u.y<v.y; return u.x<v.x; } int lowbit(int x) { return x&(-x); } void update(int place,int num,int n) { while(place<=n) { c[place]=max(c[place],num); place+=lowbit(place); } } int query(int place) { int ans=0; while(place>0) { ans=max(ans,c[place]); place-=lowbit(place); } return ans; } int dp[maxn]; int main(int argc, char const *argv[]) { #ifndef ONLINE_JUDGE freopen("/home/wzy/in.txt", "r", stdin); freopen("/home/wzy/out.txt", "w", stdout); srand((unsigned int)time(NULL)); #endif ios::sync_with_stdio(false); cin.tie(0); int n,m,k; cin>>n>>m>>k; for(int i=1;i<=k;i++) { cin>>p[i].x>>p[i].y>>p[i].s; mapx[i]=p[i].x; mapy[i]=p[i].y; } // 離散化 sort(mapx+1,mapx+1+k); sort(mapy+1,mapy+1+k); int numx,numy; numx=numy=k; numx=unique(mapx+1,mapx+1+numx)-(mapx+1); numy=unique(mapy+1,mapy+1+numy)-(mapy+1); for(int i=1;i<=k;i++) { p[i].x=lower_bound(mapx+1,mapx+numx+1,p[i].x)-mapx; p[i].y=lower_bound(mapy+1,mapy+numy+1,p[i].y)-mapy; } sort(p+1,p+1+k,cmp); for(int i=1;i<=k;i++) { dp[i]=query(p[i].y)+p[i].s; update(p[i].y,dp[i],k); } int ans=0; for(int i=1;i<=k;i++) ans=max(ans,dp[i]); cout<<ans<<endl; #ifndef ONLINE_JUDGE cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<" s."<<endl; #endif return 0; }