1475 建设国家(优先队列)

1475 建设国家

基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题

 

 

小C现在想建设一个国家。这个国家中有一个首都,然后有若干个中间站,还有若干个城市。

现在小C想把国家建造成这样的形状:选若干(可以是0个)的中间站把他们连成一条直线,然后把首都(首都也是一个中间站)连在这一条直线的左端。然后每个点可以连一个城市,特别的是最右端的点可以连接两个城市。

现在有n个城市的规划供小C选择。但是,他们那儿的交通条件比较差,他们那儿一天是2*H个小时,每个城市里面的人每天都会去首都拿一样东西,从他们所在的城市出发,到了首都之后拿了东西就走(拿东西的时间可以忽略不计),他们要在2*H个小时之内返回他们自己的家中(从家中出发到返回家中不超过2*H小时)。

每个城市有两个属性,一个是城市的直径,另外一个是能居住的人口数目。对于第i个城市而言,这两个属性分别是hi,pi。

城市的直径的意思是离这个城市出口最远的人想要出城先要在城里行走的最少的时间。

在首都,中间站,城市之间行走要花费1小时的时间。

小C想选择一些城市然后通过若干的中间站和首都连接起来,在每个人能在2*H小时返回的条件下所有城市居住的总人口数目要最多。

样例解释:最上面的蓝点表示首都,其它的蓝点表示中间站,剩下的红圈表示选择的城市。

 

Input

单组测试数据。 第一行包含两个整数n 和H (1 ≤ n ≤ 1000,1 ≤ H ≤ 1000000000),表示可供选择的城市数目和时间限制。 接下来n行,每行有两个整数hi, pi (1 ≤ hi ≤ H, 1 ≤ pi ≤ 1000),第i个城市的两个属性,即直径和能容纳人口数。

Output

输出最多能居住的人口数目。

Input示例

5 10

1 1

1 1

2 2

3 3

4 4

Output示例

11

 

 

//题目很长,读懂后,很容易想到是优先队列,但是怎么用是个问题,最下面的中间站可以放两个比较需要想法处理,看了别人代码后才懂的,写得很好,注释了一下。比较好懂

 

 1 # include <cstdio>
 2 # include <cstring>
 3 # include <cstdlib>
 4 # include <iostream>
 5 # include <vector>
 6 # include <queue>
 7 # include <stack>
 8 # include <map>
 9 # include <bitset>
10 # include <sstream>
11 # include <set>
12 # include <time.h>
13 # include <cmath>
14 # include <algorithm>
15 # pragma  comment(linker,"/STACK:102400000,102400000")
16 using namespace std;
17 # define LL          long long
18 # define pr          pair
19 # define mkp         make_pair
20 # define lowbit(x)   ((x)&(-x))
21 # define PI          acos(-1.0)
22 # define INF         0x3f3f3f3f3f3f3f3f
23 # define eps         1e-8
24 # define MOD         1000000007
25 # define MX          1005
26 /**************************/
27 
28 vector<int> ve[MX];
29 
30 int main()
31 {
32     int n,H;
33     scanf("%d%d",&n,&H);
34     for (int i=1;i<=n;i++)
35     {
36         int h,p;
37         scanf("%d%d",&h,&p);
38         int c = min(n,H-h); //最多放在第几层
39         ve[c].push_back(p);
40     }
41     priority_queue<int > Q;
42     int ans = 0, s  = 0;
43     for (int i=1;i<=n;i++) //在i层的最大效益
44     {
45         while (Q.size()>=i)
46         {
47             s+=Q.top();
48             Q.pop();
49         }
50         for (int j=0;j<ve[i].size();j++) 
51         {
52             s+=ve[i][j];
53             Q.push(-ve[i][j]);
54         }
55         while (Q.size()>i+1) //超过限制
56         {
57             s+=Q.top();
58             Q.pop();
59         }
60         ans = max(ans,s);
61     }
62     printf("%d\n",ans);
63     return 0;
64 }
View Code

 

 

 

 

posted @ 2017-08-30 22:51  happy_codes  阅读(220)  评论(0编辑  收藏  举报