分析:使用优先队列.
以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;
}
原文地址:http://blog.csdn.net/a809146548/article/details/45535165