1. 程式人生 > >1475 建設國家(優先隊列)

1475 建設國家(優先隊列)

ray 想法 name push 形狀 小時 每天 包含 接下來

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 <iostream>
 2 #include <vector>
 3 #include <queue>
 4 #include <stdio.h>
 5 using namespace std;
6 7 const int N = 1005; 8 int n,H; 9 vector <int> v[N]; 10 11 int main() 12 { 13 scanf("%d%d",&n,&H); 14 for(int i=0;i<n;i++) 15 { 16 int h,p; 17 scanf("%d%d",&h,&p); 18 int x = min(n,H-h); //最多放在第幾層 19 v[x].push_back(p); 20 } 21 22 priority_queue<int> q; 23 int ans = 0; 24 int s = 0; 25 for(int i=1;i<=n;i++) //計算在 i 層可產生的效益 26 { 27 while (q.size()>=i) 28 { 29 s+=q.top(); 30 q.pop(); 31 } 32 for(int p=0;p<v[i].size();p++) //全部加入 33 { 34 q.push(-v[i][p]); 35 s += v[i][p]; 36 } 37 while (q.size()>i+1) //最多只能放i+1個 38 { 39 s+=q.top(); 40 q.pop(); 41 } 42 ans = max(ans,s); 43 } 44 printf("%d\n",ans); 45 }
View Code

1475 建設國家(優先隊列)