poj2431 Expedition (优先队列) 挑战程序设计竞赛

题目链接:http://poj.org/problem?id=2431

Expedition

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9148   Accepted: 2673

Description

A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor drivers, the cows unfortunately managed to run over a rock and puncture the truck‘s fuel tank. The truck now leaks one unit of
fuel every unit of distance it travels.

To repair the truck, the cows need to drive to the nearest town (no more than 1,000,000 units distant) down a long, winding road. On this road, between the town and the current location of the truck, there are N (1 <= N <= 10,000) fuel stops where the cows
can stop to acquire additional fuel (1..100 units at each stop).

The jungle is a dangerous place for humans and is especially dangerous for cows. Therefore, the cows want to make the minimum possible number of stops for fuel on the way to the town. Fortunately, the capacity of the fuel tank on their truck is so large that
there is effectively no limit to the amount of fuel it can hold. The truck is currently L units away from the town and has P units of fuel (1 <= P <= 1,000,000).

Determine the minimum number of stops needed to reach the town, or if the cows cannot reach the town at all.

Input

* Line 1: A single integer, N

* Lines 2..N+1: Each line contains two space-separated integers describing a fuel stop: The first integer is the distance from the town to the stop; the second is the amount of fuel available at that stop.

* Line N+2: Two space-separated integers, L and P

Output

* Line 1: A single integer giving the minimum number of fuel stops necessary to reach the town. If it is not possible to reach the town, output -1.

Sample Input

4
4 4
5 2
11 5
15 10
25 10

Sample Output

2

Hint

INPUT DETAILS:

The truck is 25 units away from the town; the truck has 10 units of fuel. Along the road, there are 4 fuel stops at distances 4, 5, 11, and 15 from the town (so these are initially at distances 21, 20, 14, and 10 from the truck). These fuel stops can supply
up to 4, 2, 5, and 10 units of fuel, respectively.

OUTPUT DETAILS:

Drive 10 units, stop to acquire 10 more units of fuel, drive 4 more units, stop to acquire 5 more units of fuel, then drive to the town.

这是挑战程序设计竞赛上的关于 堆 以及 优先队列运用的例题,书上给出的思路非常巧妙

因为求得是最优解,需要尽可能少的加油站,所以我们每次希望去加油的时候 加最大的那个,因而将加油站push进priority_queue(堆结构,默认每次弹出最大值)

从起点开始跑,把路程通过加油站分成几部分,每一部分只要通过加油能到达加油站即可,,因而,把终点也视为加油站 距离L,加油量 0;

#include<cstdio> //输入量较大,所以用c风格来输入输出, ac时间 16ms , 全部换成c++的风格则需要 313ms
#include<queue>
#include<algorithm>
using namespace std;
struct node{
	int a1,b1;
};
int cmp(const node& a,const node& b){
	return a.a1<b.a1;
}
int main(){
	priority_queue<int> pq;
	int n;
	node no[10010];
	while(scanf("%d",&n)!=EOF){
		for(int i=0;i<n;i++){
			scanf("%d%d",&no[i].a1,&no[i].b1);
		}
		int L,P,cnt=0,sign=0;
			scanf("%d%d",&L,&P);
		for(int i=0;i<n;i++){  //题目要求给的a1是当前与终点的距离,我们转换为与起点的距离
			no[i].a1=L-no[i].a1;
		}
		sort(no,no+n,cmp);
		int index=0;
		//pq.push(P);
		int pos=0;
		no[n].a1=L;  //将终点设为加油站
		no[n].b1=0;
		n++;
		for(int i=0;i<n;i++){
			 int d=no[i].a1-pos; //当前需要走的距离
			 while(P<d){
				 if(pq.empty()){ //油箱为空
					 puts("-1");
					 sign=1;
					 break;
				 }
				 else{
					 P+=pq.top();
					 pq.pop();
					 cnt++;
				 }
			 }
			 P-=d;
			 pos=no[i].a1;
			 pq.push(no[i].b1);
		}
		if(!sign){
			printf("%d\n",cnt);
		}

	}
	return 0;
}

下面是另一种方法

#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
struct node{
	int a1,b1;
}no[10010];
int cmp(const node&a, const node&b){
	return a.a1<b.a1;
}
int main(){
	int t;
	priority_queue<int>pq;
	while(scanf("%d",&t)!=EOF){
		while(!pq.empty())
			pq.pop();
		for(int i=0;i<t;i++){
			scanf("%d%d",&no[i].a1,&no[i].b1);
		}
		int l,p;
		scanf("%d%d",&l,&p);
		for(int i=0;i<t;i++){
			no[i].a1=l-no[i].a1;
		}
		sort(no,no+t,cmp);
		int cur=p;//当前位置
		int i=0;
		int cnt=0;
		while(cur<l){ //如果还没到终点
			while(no[i].a1<=cur&&i<t){ //能加油就尽量加
				pq.push(no[i].b1);
				i++;
			}
			if(pq.empty()) break;
			cur+=pq.top(); 当前位置往前移动 (加上当前最大的加油站里的油)
			pq.pop();
			cnt++;
		}
		if(cur>=l) //当最远跑的距离超过终点
			printf("%d\n",cnt);
		else
			printf("-1\n");
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-02 07:01:26

poj2431 Expedition (优先队列) 挑战程序设计竞赛的相关文章

《挑战程序设计竞赛》课后练习题解集——3.4 熟练掌握动态规划

<挑战程序设计竞赛>课后练习题解集——3.4 熟练掌握动态规划 状态压缩DP POJ 2441  有N头牛,M个槽,N,M≤20,每头牛只在指定的pi个槽里进食,不与其他牛共享槽.问有多少种分配方案. dp[i][S],当前第i头牛要进食,槽的使用状态为S 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 using namespace std; 5 6 int n, m; 7 in

POJ 3420 Quad Tiling 题解 《挑战程序设计竞赛》

POJ 3420 Quad Tiling贴瓷砖:4*N的地板上用2*1的瓷砖铺满,求所有方案数对M求余.3.4熟练掌握动态规划矩阵的幂久违地上了节课,太无聊,只好刷一题.假设S[n]表示填满n时的方案数,有S[0]=1.定义矩阵M[p][q] := 边缘p和边缘q可以拼合时取1,否则取0所谓的可以拼合表示,两个边缘拼起来后长度为1(为2就拼接不起来了),且内部缝隙可以用2*1的瓷砖填满.那么M就有一些简单的性质了,比如M的第一行应该是:0 0 0 0 0 0... 继续阅读:码农场 » POJ

POJ 3411 Paid Roads 题解 《挑战程序设计竞赛》

POJ 3411 Paid Roads开路:N个城市间有m条单向路,分别从a到b,可以在c处交P路费,也可以直接交R路费.那么问题来了,你的挖掘机怎么开最省钱?3.4熟练掌握动态规划状态压缩DP乍一看可以Dijkstra,实际上的确可以Dijkstra.不过多了一个预交费的c,所以在遍历的时候多了一维状态,这个维度储存当前走过的城市集合.在Dijkstra的时候,如果走过了c那么就有两个选择,选其中最省的即可:否则没得选.#include <iostream> #include&nb.

字符串HASH模板 取自挑战程序设计竞赛(第2版)

/*===================================================* 从b串中寻找和a串长度相同的子串,返回开始位置 不保证绝对正确,发生冲突概率为O(sqrt(n)), n为哈希函数的最大值 \*===================================================*/ #define ull unsigned long long const ull B = 1e8+7; /*according to the book*/

[转] AOJ 0525 Osenbei《挑战程序设计竞赛(第2版)》练习题答案

来自 码农场 ? AOJ 0525 Osenbei<挑战程序设计竞赛(第2版)>练习题答案 只把代码复制过来,原博的其他分析请看链接. 1 #include <iostream> 2 #include <bitset> 3 #include <algorithm> 4 5 using namespace std; 6 7 bitset<10000> cookie[10]; 8 9 ///////////////////////////SubMai

POJ 2836 Rectangular Covering 题解 《挑战程序设计竞赛》

POJ 2836 Rectangular Covering铺地板:坐标平面上有n各点,用任意大小(非零)的地板砖覆盖它们,求最省的地板砖总面积.3.4熟练掌握动态规划状态压缩DP先预处理数据,将n个点两两组合形成n * (n-1) / 2个矩形,计算每个矩形的面积和内部点个数.接着利用预处理数据来枚举,定义dp[S] := 矩形集为S时的最省面积先假设平面上没有矩形,那么dp[0]=0,接着一个一个地往平面上加矩形,递推关系是:dp[新矩形集合] = min(dp[新矩形集合], dp[旧矩形集

Aizu 2249Road Construction 单源最短路变形《挑战程序设计竞赛》模板题

King Mercer is the king of ACM kingdom. There are one capital and some cities in his kingdom. Amazingly, there are no roads in the kingdom now. Recently, he planned to construct roads between the capital and the cities, but it turned out that the con

38天刷完挑战程序设计竞赛&amp;数论概论计划

现在是2017年12月6日22:03:36,在做数论概论的chapter6线性方程与最大公因数的习题时,粗略地翻了一下挑战程序设计竞赛,感觉相见恨晚:遂决定38天刷完挑战程序设计竞赛和数论概论. 时间:2017年12月7日00:00:00 -- 2018年1月15日00:00:00 目前进度:数论概论完成前6章,挑战程序设计竞赛完成0 目标:刷完数论概论44章,理解所有定理和证明,刷完全部练习 刷完挑战程序设计竞赛4章共406页,理解所有知识点和证明,刷完全部例题和习题(此目标可以调整,比如跳过

挑战程序设计竞赛 PDF下载

网盘下载地址:挑战程序设计竞赛 PDF下载 – 易分享电子书PDF资源网 作者: 秋叶拓哉 / 岩田阳一 / 北川宜稔 出版社: 人民邮电出版社 原作名: プログラミングコンテストチャレンジブック [第2版] ~問題解決のアルゴリズム活用力とコーディングテクニックを鍛える~ 译者: 巫泽俊 / 庄俊元 / 李津羽 出版年: 2013-7-1 内容简介 · · · · · · 世界顶级程序设计高手的经验总结 [ACM-ICPC全球总冠军]巫泽俊主译 日本ACM-ICPC参赛者人手一册 本书对程序设