Traversal
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 861 Accepted Submission(s): 306
Problem Description
Xiao Ming is travelling, and today he came to the West Lake, to see people playing a game, this game is like this, lake placed n-box, from 1 to n label. These boxes are floating in the water, there are some gold inside each box. Then participants from coast to jump the other side, each box have its’s height, you can only jump from lower height to higher height, and from a small label to a big label, you can skip some of the middle of the box. Suppose the minimum height is this side, the other side has the maximum height. Xiao Ming would like to jump how to get the most gold? He now needs your help.
Input
There are multiple test cases. Each test case contains one integer N , representing the number of boxes . The following N lines each line contains two integers hi and gi , indicate the height and the number of gold of the ith box.
1 < = N < 100 001
0 < hi < 100 000 001
0 < gi < = 10000
1 < = N < 100 001
0 < hi < 100 000 001
0 < gi < = 10000
Output
For each test case you should output a single line, containing the number of maximum gold XiaoMing can get.
Sample Input
4 1 1 2 2 2 3 5 1 1 1 10000
Sample Output
5 10000
题意:有n个木箱,每个木箱都有一个高度和相应的黄金。现在要跳到木箱上取木箱的黄金,规定每次只能跳到比上一个木箱高的且标签大的木箱上。现在要求出最多能得到的黄金。
思路:容易想到用dp来做。按标签从前到后搜索,关键是每次找出比当前高度低的且黄金数是最多的状态,而这个状态可以用树状数组来找,树状数组c[i]保存的是已跳到高度为i的木箱时取得的最大黄金数。题目高度范围较大,所以要离散化,每次用二分找出离散化后某个高度对应的下标即可。记得每次都要更新树状数组。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
#include <cstdlib>
#define L(rt) (rt<<1)
#define R(rt) (rt<<1|1)
using namespace std;
const int maxn=100005;
struct node
{
int hi,gi,id;
}box[maxn];
int c[maxn],index[maxn],h[maxn];
int n,cnt;
int lowbit(int x)
{
return x&(-x);
}
int query(int x)
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans=max(ans,c[i]);
return ans;
}
void update(int x,int val)
{
for(int i=x;i<=cnt;i+=lowbit(i))
c[i]=max(c[i],val);
}
int binary(int x)
{
int low=1,high=cnt,mid;
while(low<=high)
{
mid=(low+high)>>1;
if(h[mid]==x) return mid;
else if(h[mid]<x) low=mid+1;
else high=mid-1;
}
return -1;
}
int main()
{
while(~scanf("%d",&n))
{
memset(c,0,sizeof(c));
cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&box[i].hi,&box[i].gi);
if(binary(box[i].hi)==-1)
h[++cnt]=box[i].hi;
}
sort(h+1,h+cnt+1);
int ans=0,t,index;
for(int i=1;i<=n;i++)
{
index=binary(box[i].hi);
t=query(index-1);
ans=max(ans,t+box[i].gi);
update(index,t+box[i].gi);
}
printf("%d\n",ans);
}
return 0;
}