Codevs 挂缀

题目描述 Description

“珠缀花蕊,人间几多酸泪”…… 
挂缀在很早就被人们作为一种装饰品,垂坠的风韵,华丽摇曳的摆动,展现出一种与众不同的优雅与高贵。而我们的主人公小Q,正想买一条漂亮的挂缀放在寝室里作为装饰。 
挂坠的构成,是由若干粒缀珠相互连接而成。每一个缀珠由三部分组成:分别是珠子、珠子上方的连接环与珠子下方的挂钩(如下图) 。我们可以简单的认为从上往下数的第 i 个缀珠是将它的连接环套在其上方(也就是第 i-1 个)缀珠的挂钩之上(第一个除外) 。小 Q想买一根足够长的挂缀,这样显得更有韵味☺ 

然而商店的老板告诉小Q,挂缀是不可能做到任意长的,因为每一个珠子都受到重力作用,对其上方的挂钩有一定的拉力,而挂钩的承受能力是有限的。老板还告诉小 Q,他一共拥有 N 个珠缀(假设每一个珠缀都很漂亮,小 Q 都很喜欢) ,每个珠缀都有其各自的重量与承受能力。一个挂缀是稳定的,当且仅当对于其上的每一个珠缀,它下方所有珠缀的重量和(不包含自身)不超过其挂钩的承受能力。 
小Q希望她的挂缀尽量长,你能帮她计算出最长可能的稳定挂缀么?当然,如果有多个可选方案,小Q希望总重量最小的。

输入描述 Input Description

 第一行包含一个正整数 N,表示商店拥有的珠缀数目。
接下来 N行,每行两个整数(Ci , Wi),分别表示第i 个珠缀的承受能力与重量。

输出描述 Output Description

包行两行。第一行包含一个整数L,表示可以找到的最长稳定挂缀长度。

第二行包含一个整数 W,表示可以找到的长度为 L 的稳定挂缀中的最小重量和。

样例输入 Sample Input


3 5 
5 1 
3 2 
4 6

样例输出 Sample Output


8

数据范围及提示 Data Size & Hint

对于 30%的数据,N ≤ 10000; 
对于 100%的数据,N ≤ 200000; 
对于所有的数据,Wi, Ci不超过231

看到题目来源CTSC07年国家队选拔赛的时候我几乎是崩溃的。。然后看了眼数据范围。。继续崩溃。。。

这道题是一道特别特别特别经典的贪心。。为什么说是贪心呢?因为我只需要升序排列,看当前挂缀的承重能否负担得起当前重量。这样我们在O(n)的时间内得到了一个长序列,并且我们可以证明的是  最后的答案一定是这个长序列其中的子序列。

那么从上往下for,如果当前挂缀的重量小于我现在的挂缀承重,那么添加进去。如果存在一个挂缀的承重大于某一个并且重量<=这一个,那么替换这个挂缀。既然可以这样贪心,那么我们可以用堆来进行维护,相应的操作就是pop和push。

下面是代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct hq{
    long long wgt,f,sum;
    bool operator <(hq const &a) const
      {return sum<a.sum;}
}a[1000001];
int n;
long long nowwgt=0,nowl=0;
priority_queue<int> q;
int main()
{
    int i;
    scanf("%d",&n);
    for (i=1;i<=n;++i)
      {
        scanf("%I64d%I64d",&a[i].f,&a[i].wgt);
        a[i].sum=a[i].f+a[i].wgt;
      }
    sort(a+1,a+n+1);
    for (i=1;i<=n;++i)
      {
        if (nowwgt<=a[i].f) {q.push(a[i].wgt); nowl++; nowwgt=nowwgt+a[i].wgt;}
        else if (q.top()>a[i].wgt) {nowwgt=nowwgt-q.top()+a[i].wgt; q.pop(); q.push(a[i].wgt);}
      }
    printf("%lld\n%lld\n",nowl,nowwgt);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值