题意:
小C现在想建设一个国家。这个国家中有一个首都,然后有若干个中间站,还有若干个城市。
现在小C想把国家建造成这样的形状:选若干(可以是0个)的中间站把他们连成一条直线,然后把首都(首都也是一个中间站)连在这一条直线的左端。然后每个点可以连一个城市,特别的是最右端的点可以连接两个城市。
现在有n个城市的规划供小C选择。但是,他们那儿的交通条件比较差,他们那儿一天是2*H个小时,每个城市里面的人每天都会去首都拿一样东西,从他们所在的城市出发,到了首都之后拿了东西就走(拿东西的时间可以忽略不计),他们要在2*H个小时之内返回他们自己的家中(从家中出发到返回家中不超过2*H小时)。
每个城市有两个属性,一个是城市的直径,另外一个是能居住的人口数目。对于第i个城市而言,这两个属性分别是hi,pi。
城市的直径的意思是离这个城市出口最远的人想要出城先要在城里行走的最少的时间。
在首都,中间站,城市之间行走要花费1小时的时间。
小C想选择一些城市然后通过若干的中间站和首都连接起来,在每个人能在2*H小时返回的条件下所有城市居住的总人口数目要最多。
样例解释:最上面的蓝点表示首都,其它的蓝点表示中间站,剩下的红圈表示选择的城市。
单组测试数据。 第一行包含两个整数n 和H (1 ≤ n ≤ 1000,1 ≤ H ≤ 1000000000),表示可供选择的城市数目和时间限制。 接下来n行,每行有两个整数hi, pi (1 ≤ hi ≤ H, 1 ≤ pi ≤ 1000),第i个城市的两个属性,即直径和能容纳人口数。
输出最多能居住的人口数目。
5 10 1 1 1 1 2 2 3 3 4 4
11
思路:
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
struct node {
int t, v;
bool operator < (const node &b) const {
if (t == b.t) return v > b.v;
return t < b.t;
}
}a[MAXN];
int main() {
//freopen("in.txt", "r", stdin);
int n, h, Max = 1;
scanf("%d%d", &n, &h);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &a[i].t, &a[i].v);
a[i].t = h - a[i].t;
Max = max(Max, a[i].t);
}
sort (a + 1, a + 1 + n);
priority_queue <int, vector <int>, greater<int> > que;
int ans = 0, now = 1, res = 0;
for (int i = 1; i <= n; i++) {
if (a[i].t == 0) continue;
if (a[i].t == now - 1) {
ans = max(ans, res + a[i].v); // 这里假设最后连接两个城市的情况,直接更新ans
if (!que.empty() && a[i].v > que.top()) {
res += a[i].v - que.top(); // 这里用当前城市来替代之前已经安排的城市,使最优值更优
que.pop(); que.push(a[i].v);
}
}
else {
++now;
que.push(a[i].v); // 时限符合条件,直接把当前城市安排到最后
res += a[i].v;
}
ans = max(ans, res);
}
printf("%d\n", ans);
return 0;
}