【2018ccpc區域賽網路賽】【hdu6447 YJJ's Salesman】【dp+離散化+樹狀陣列/線段樹優化】
阿新 • • 發佈:2019-01-05
連結:
分析:二維座標排序,x->大,y->小,由於我們每次走必須x,y均變大,那麼相當於只要考慮排序後的y的值。從左往右考慮y,dp[i]=max(dp[j])+val[i](i表示第i個點),由於y的資料範圍為1e9,需要離散化,然後用樹狀陣列維護求最大。
程式碼:
#pragma warning(disable:4996) #include<bits/stdc++.h> using namespace std; typedef pair<int, int> pii; typedef pair<double, int>pdi; typedef long long ll; #define CLR(a,b) memset(a,b,sizeof(a)) #define _for(i, a, b) for (int i = a; i < b; ++i) const int mod = (int)1e9 + 7; const long double eps = 1e-10; const int maxn = 1e5 + 7; const int INF = 0x3f3f3f3f; struct node { ll x, y, z; }k[maxn]; ll c[maxn]; ll lowbit(ll i) { return i & (-i); } ll getsum(ll x) { ll res = 0; while (x) { res =max(res, c[x]); x -= lowbit(x); } return res; } void add(ll x, ll v) { while (x <= 1e5) { c[x] = max(c[x], v); x += lowbit(x); } } int main() { int t; scanf("%d", &t); while (t--) { CLR(c, 0); ll n; scanf("%lld", &n); for (int i = 1; i <= n; i++) { scanf("%lld%lld%lld", &k[i].x, &k[i].y, &k[i].z); } sort(k + 1, k + 1 + n, [](const node &l, const node &r) { return l.y < r.y; }); int cnt = 1; for (int i = 1; i <= n; ++i) { if (k[i].y != k[i + 1].y) k[i].y = cnt++; else k[i].y = cnt; } sort(k + 1, k + 1 + n, cmp); ll maxv = 0; for (int i = 1; i <= n; i++) { int tmp = getsum(k[i].y - 1) + k[i].z;//同行不能加,故要減1 add(k[i].y, tmp); } printf("%lld\n", getsum(n)); } }