您的位置:首页 > 其它

hdu 3607 Traversal(树状数组+离散化)

2013-08-08 20:05 309 查看

Traversal

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 861 Accepted Submission(s): 306



[align=left]Problem Description[/align]
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.

[align=left]Input[/align]
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

[align=left]Output[/align]
For each test case you should output a single line, containing the number of maximum gold XiaoMing can get.

[align=left]Sample Input[/align]

4
1 1
2 2
2 3
5 1

1
1 10000


[align=left]Sample Output[/align]

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: