4 1 1 2 2 2 3 5 1 1 1 10000
5 10000
#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 200010;
const int inf = -0x3f3f3f3f;
int dp[N];
int xis[N];
int n, cnt;
struct node
{
int l, r;
int val;
}tree[N << 2];
struct node2
{
int g;
int h;
}box[N];
int BinSearch(int val)
{
int l = 1, r = cnt, mid;
int ans;
while (l <= r)
{
mid = (l + r) >> 1;
if (xis[mid] > val)
{
r = mid - 1;
}
else if (xis[mid] < val)
{
l = mid + 1;
}
else
{
ans = mid;
break;
}
}
return ans;
}
void build(int p, int l, int r)
{
tree[p].l = l;
tree[p].r = r;
tree[p].val = inf;
if (l == r)
{
return;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
}
void update(int p, int pos, int val)
{
if (tree[p].l == tree[p].r)
{
tree[p].val = val;
return;
}
int mid = (tree[p].l + tree[p].r) >> 1;
if (pos <= mid)
{
update(p << 1, pos, val);
}
else
{
update(p << 1 | 1, pos, val);
}
tree[p].val = max(tree[p << 1].val, tree[p << 1 | 1].val);
}
int query(int p, int l, int r)
{
if (l <= tree[p].l && tree[p].r <= r)
{
return tree[p].val;
}
int mid = (tree[p].l + tree[p].r) >> 1;
if (r <= mid)
{
return query(p << 1, l, r);
}
else if (l > mid)
{
return query(p << 1 | 1, l, r);
}
else
{
return max(query(p << 1, l, mid), query(p << 1 | 1, mid + 1, r));
}
}
int main()
{
while (~scanf("%d", &n))
{
int ans = 0;
cnt = 1;
xis[0] = 0;
for (int i = 1; i <= n; ++i)
{
scanf("%d%d", &box[i].h, &box[i].g);
xis[++cnt] = box[i].h;
}
sort (xis, xis + cnt + 1);
cnt = unique(xis, xis + cnt + 1) - xis - 1;
build(1, 1, cnt);
dp[0] = 0;
update(1, 1, dp[0]);
for (int i = 1; i <= n; ++i)
{
int j = BinSearch(box[i].h), last;
if (j == 1)
{
dp[i] = box[i].g;
}
else
{
last = query(1, 1, j - 1);
dp[i] = last + box[i].g;
}
update(1, j, dp[i]);
ans = max(ans, dp[i]);
}
printf("%d\n", ans);
}
return 0;
}原文地址:http://blog.csdn.net/guard_mine/article/details/41786637