HDU4546(优先队列)

题目:比赛难度

 

题意:给一个整数序列,长度为n,求在这个序列的子序列中和为第m大的数。

 

分析:

设置优先级队列

{

    sum:   当前和

    next:  加入下个元素的和

    ith:   将要考虑的下个元素

}


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

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

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

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

 

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <queue>

using namespace std;
const int N=100011;

int a[N];
int n,m;

struct Node
{
    int sum;
    int next;
    int ith;
    Node(){};
    Node(int _sum,int _next,int _ith)
    {
        sum=_sum;
        next=_next;
        ith=_ith;
    }
    bool operator < (const Node &b) const
    {
        return b.next<next;
    }
};

int Solve(int m)
{
    priority_queue<Node> Q;
    Node tmp;
    tmp.sum=0;
    tmp.next=a[0];
    tmp.ith=0;
    Q.push(tmp);
    int cnt=0;
    a[n]=0;
    while(cnt<m)
    {
        tmp=Q.top();
        Q.pop();
        if(tmp.ith>=n) continue;
        Q.push(Node(tmp.sum,tmp.sum+a[tmp.ith+1],tmp.ith+1));
        Q.push(Node(tmp.next,tmp.next+a[tmp.ith+1],tmp.ith+1));
        cnt++;
    }
    for(m=0;!Q.empty();m++)
    {
        a[m]=Q.top().sum;
        Q.pop();
    }
    sort(a,a+m);
    return a[m-1];
}

int main()
{
    int t,i,tt=1;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(i=0;i<n;i++)
            cin>>a[i];
        sort(a,a+n);
        printf("Case #%d: %d\n",tt++,Solve(m));
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值