HDU ACM 4546 比赛难度->优先队列

分析:使用优先队列.

以next为优先级,小的先出队

读入数据后排序,初始化队列第一个元素(0,a[0],0)

每次出队一个元素,入队(sum,sum+a[nextid+1],nextid+1),(next,next+a[nextid+1],nextid+1),即是否加上a[nextid+1]都考虑进去了。

这样每次新加入的元素都是下一个最小的(next),进行m次就得到了第m小。

#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;

struct A
{
	A(){}
	A(int s,int n,int ni):sum(s),next(n),nextid(ni)
	{
	}
	bool operator<(const A& a)const
	{
		return this->next>a.next;
	}
	int sum;    //当前和
	int next;   //加入下个元素和
	int nextid;  //下个元素id
};

int a[10010];
int n,m;

int Run()
{
	priority_queue<A> q;
	A tmp;
	int cnt;

	q.push(A(0,a[0],0));
	cnt=0;
	while(!q.empty())
	{
		tmp=q.top();
		q.pop();

		if(tmp.nextid>=n)  //超出范围,却多计算了a[n],设置的结尾值
			continue;
		q.push(A(tmp.sum,tmp.sum+a[tmp.nextid+1],tmp.nextid+1));
		q.push(A(tmp.next,tmp.next+a[tmp.nextid+1],tmp.nextid+1));
		cnt++;
		if(cnt==m)
			return tmp.next;
	}
}

int main()
{
	int T,i,c;

	scanf("%d",&T);
	c=0;
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(i=0;i<n;i++)
			scanf("%d",&a[i]);
		sort(a,a+n);
		a[n]=0;
		printf("Case #%d: %d\n",++c,Run());
	}
	return 0;
}
时间: 2024-11-02 19:12:19

HDU ACM 4546 比赛难度->优先队列的相关文章

HDU 4546 比赛难度(优先队列)

HDU 4546 比赛难度 题目链接 思路:由于m不是很大,如果用一个优先队列维护,如果每次能保证加入的值是最小的,那么只需要加入m次就能完成了,时间复杂度足够,那么如何保证呢,就把数列排序,维护优先队列为当前和加下一个位置和的最小值,每次一个出队,把下一个位置取于不取在入队,最后求出答案即可 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> usin

hdu 4546 比赛难度

优先队列,也是看了别人的代码才有的思路 #include<iostream> #include<algorithm> #include<queue> #define maxn 100000+5 using namespace std; struct stu { int sum,id; friend bool operator<(stu x,stu y) { return x.sum>y.sum; } }; priority_queue<stu>m

[ACM] hdu 1285 确定比赛名次 (拓扑排序)

确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 10358    Accepted Submission(s): 4046 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直

HDU 1285 确定比赛名次(拓扑排序+优先队列)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前.现在请你编程序确定排名. Input 输入有若干组,每组中的第一行为二个数N(1<=N<

ACM: HDU 1285 确定比赛名次 - 拓扑排序

HDU 1285 确定比赛名次 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前.现在请你编程序确定排名

HDU ACM 1025 Constructing Roads In JGShining&amp;#39;s Kingdom-&amp;gt;二分求解LIS+O(NlogN)

#include<iostream> using namespace std; //BFS+优先队列(打印路径) #define N 500005 int c[N]; int dp[N]; //dp[i]保存的是长度为i的最长不降子序列的最小尾元素 int BS(int n,int x) //二分查找下标,当x比全部元素小时下标为1,比全部元素大时下标为n+1. { int low,high,mid; low=1,high=n; while(low<=high) { mid=(low+h

HDU 1285 确定比赛名次(拓扑排序模板)

题意还是比较容易理解的,关键要看到后面的:合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前: 思路:这道题就是拓扑排序的经典应用了,用队列做的考虑优先编号小的出队就可以了. 拓扑排序: 拓扑排序是对有向无回路图(DAG)顶点的一种排序,它使得如果存在从u到v的有向路径,那么满足序列中u在v前. 所以我们的算法可以描述为这样一个过程: 1.找到整个图中所有的度为0的点,将这些点压进队列(栈)中 2.从队列(栈)中取出一点,输出,将该点及它的边删除,找到它所指向的点,如果改点是一个原点(删

HDU ACM 1025 Constructing Roads In JGShining&#39;s Kingdom-&gt;二分求解LIS+O(NlogN)

#include<iostream> using namespace std; //BFS+优先队列(打印路径) #define N 500005 int c[N]; int dp[N]; //dp[i]保存的是长度为i的最长不降子序列的最小尾元素 int BS(int n,int x) //二分查找下标,当x比所有元素小时下标为1,比所有元素大时下标为n+1. { int low,high,mid; low=1,high=n; while(low<=high) { mid=(low+h

HDU ACM 1103 Flo&#39;s Restaurant

分析:借助STL的min_element实现.每次更新最先被占用的桌子,具体见注释. #include<iostream> #include<algorithm> using namespace std; int main() { int A,B,C; char s[10]; int a[102],b[102],c[102]; int curtime,count,ans; int *p; //桌子最先空闲时间 while(cin>>A>>B>>C