poj 2431 poj 3253 优先队列的运用

2024-09-09 16:18
文章标签 队列 poj 优先 运用 3253 2431

本文主要是介绍poj 2431 poj 3253 优先队列的运用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

poj 2431:

题意:

一条路起点为0, 终点为l。

卡车初始时在0点,并且有p升油,假设油箱无限大。

给n个加油站,每个加油站距离终点 l 距离为 x[i],可以加的油量为fuel[i]。

问最少加几次油可以到达终点,若不能到达,输出-1。


解析:

《挑战程序设计竞赛》:

“在卡车开往终点的途中,只有在加油站才可以加油。但是,如果认为“在到达加油站i时,就获得了一次可以在之后任何位置加一次fuel[i]升油的机会”。

在解决问题上也可以这样做,之后需要加油时,认为在之前经过该加油站加的油就行了。

那么,因为希望到达终点时的加油次数尽量少,所以当燃料为0了之后再进行加油看上去是一个不错的方法。在燃料为0时,应该使用哪个加油站来加油呢?

显然,应该选择加油量fuel[i]最大的加油站。这里就用到了优先队列。”


所以,按题中,装换排序,用优先队列就行了。


代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 10000 + 10;
const double eps = 1e-9;int n, l, p;struct Node
{int x, fuel;bool operator<(Node a)const{return fuel < a.fuel;}
} node[maxn];bool cmp(Node a, Node b)
{return a.x < b.x;
}int main()
{
#ifdef LOCALfreopen("in.txt", "r", stdin);
#endif // LOCALwhile (~scanf("%d", &n)){for (int i = 0; i < n; i++){scanf("%d%d", &node[i].x, &node[i].fuel);}scanf("%d%d", &l, &p);for (int i = 0; i < n; i++)node[i].x = l - node[i].x;sort(node, node + n, cmp);node[n].x = l;node[n++].fuel = 0;
//        for (int i = 0; i < n; i++)
//        {
//            cout << node[i].x << " " << node[i].fuel << endl;
//        }priority_queue<Node> q;
//        q.push(node[0]);
//        q.push(node[1]);
//        q.push(node[2]);
//        q.push(node[3]);
//        cout <<endl;
//        while (!q.empty())
//        {
//            cout << q.top().fuel << endl;
//            q.pop();
//        }bool flag = true;int pos = 0, ans = 0;for (int i = 0; i < n; i++){int d = node[i].x - pos;while (p < d){if (q.empty()){flag = false;break;}p += q.top().fuel;q.pop();ans++;}if (!flag)break;pos = node[i].x;p -= d;q.push(node[i]);}if (!flag)ans = -1;printf("%d\n", ans);}return 0;
}


poj 3253:

贪心+优先队列。

greater的运用。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <climits>
#include <cassert>
#define LL long long
#define lson lo, mi, rt << 1
#define rson mi + 1, hi, rt << 1 | 1using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 20000 + 10;
const double eps = 1e-9;int n;
int l[maxn];void solve()
{LL ans = 0;priority_queue<int, vector<int>, greater<int> > q;for (int i = 0; i < n; i++)q.push(l[i]);
//    cout << n <<endl;
//    cout << q.size()    << endl;while (q.size() > 1){int l1, l2;l1 = q.top();q.pop();l2 = q.top();q.pop();
//        cout << l1 << l2 << endl;ans += (LL)l1 + (LL)l2;q.push(l1 + l2);}printf("%lld\n", ans);
}int main()
{
#ifdef LOCALfreopen("in.txt", "r", stdin);
#endif // LOCALwhile (~scanf("%d", &n)){for (int i = 0; i < n; i++)scanf("%d", &l[i]);solve();}return 0;
}


这篇关于poj 2431 poj 3253 优先队列的运用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1151653

相关文章

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一