YJJ's SalesmanTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Problem Description YJJ is a salesman who has traveled through western country. YJJ is always on journey. Either is he at the destination, or on the way to destination.
Input The first line of the input contains an integer T (1≤T≤10) ,which is the number of test cases.
Output The maximum of dollars YJJ can get.
Sample Input 1 3 1 1 1 1 2 2 3 3 1
Sample Output 3
|
題目大意是說在一個1e9*1e9的地圖上有1e5個村莊,每個村莊有一定的利潤。每次只能從(x,y)走到(x+1,y)或(x,y+1)或(x+1,y+1),並且只有是用最後一種走法走到村莊的才能獲得該村莊的利益。
我的做法是先把村莊按照縱座標從小到大,橫座標從大到小排序一下(橫座標從小到大是類似01揹包),再把橫座標離散化一下這樣遍歷村莊的時候就能直接在一個一維的數組裏找最大利益並更新當前橫座標的利益,用線段樹或樹狀數組維護最大利益即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
typedef long long ll;
int maxx[4 * maxn];
int n;
int x[maxn];
struct fun
{
int x,y,v;
}z[maxn];
int cntx;
void update(int l, int r, int rt, int p, int v)
{
if (p <= l && r <= p)
{
maxx[rt] = max(maxx[rt], v);
return;
}
int mid = (l + r) >> 1;
if (p <= mid)
update(l, mid, rt << 1, p, v);
else
update(mid + 1, r, (rt << 1) + 1, p, v);
maxx[rt] = max(maxx[rt << 1], maxx[(rt << 1) + 1]);
}
int query(int l, int r, int rt, int l1, int r1)
{
if (l > r || l1 > r1)
return 0;
if (l1 <= l && r <= r1)
return maxx[rt];
int mid = (l + r) >> 1;
int ans1,ans2;
ans1 = ans2 = 0;
if (l1 <= mid)
ans1 = query(l, mid, rt << 1, l1, r1);
if (r1 > mid)
ans2 = query(mid + 1, r, (rt << 1) + 1, l1, r1);
return max(ans1, ans2);
}
bool cmp(fun a, fun b)
{
if (a.y != b.y)
return a.y < b.y;
return a.x > b.x;
}
int main()
{
// freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
while (t--)
{
memset(maxx, 0, sizeof(maxx));
cntx = 1;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d%d%d", &z[i].x, &z[i].y, &z[i].v);
x[i] = z[i].x;
}
sort(x, x + n);
for (int i = 0; i < n; i++)
z[i].x = lower_bound(x, x + n, z[i].x) - x + 1;
sort(z, z + n, cmp);
int ans = 0;
int tmp;
for (int i = 0; i < n; i++)
{
tmp = query(1, n, 1, 1, z[i].x - 1) + z[i].v;
ans = max(ans, tmp);
update(1, n, 1, z[i].x, tmp);
}
printf("%d\n", ans);
}
return 0;
}