【BZOJ】4619 [Wf2016] Swap Space

Description

你有许多电脑,它们的硬盘用不同的文件系统储存数据。你想要通过格式化来统一文件系统。格式化硬盘可能使它的容量发生变化。为了格式化,你需要买额外的硬盘。当然,你想要买容量最小的额外储存设备以便省钱。你可以按任意顺序格式化硬盘。格式化之前,你要把该硬盘上所有数据移到一个或更多的其他硬盘上(可以分割数据)。格式化后,该硬盘可以立刻开始使用。你没有必要把数据放到它原来所在的硬盘上。数据也可以被放到你额外买的硬盘上。举个例子,假设你有 4 个硬盘ABCD,容量分别为 6133(GB) 。新的文件系统下,它们的容量变为 6755(GB) 。如果你只买 1GB 额外空间,你可以把 B 硬盘的数据放过去然后格式化硬盘B。现在你的 B 硬盘有7GB容量了,那么你就可以把A的数据放过去然后格式化 A ,最后把CD的数据放到 A 上,再格式化C D

Input

第一行一个数 n1n1,000,000 ,表示你的硬盘数。接下来 n 行,每行两个数a b ,分别表示该硬盘的原容量和新文件系统下的容量。所有容量都以GB为单位,且 1a,b1,000,000,000

Output

输出如果要格式化所有硬盘,你最少需要购买多少额外空间 GB

Solution

先说一个结论:
先对所有 a<b 的硬盘按 a 升序做,再把剩下硬盘按b降序做

首先对于 a 升序部分,考虑只在需要的时候买空间,那么对于一个硬盘,它格式化后肯定能提供更多的空间(减少下一个硬盘启动格式化所需的空间)。并且,启动某个硬盘的格式化的时候,购买的额外空间量一定小于直接开启它所需空间量。

对于剩下部分,考虑对于两个硬盘,分别为a1,b1,a2,b2,两种格式化的顺序分别会有以下空间情况(需要空间为 G b1>b2):
第一步: G1a1 G2a2 无法比较
第二步: G1a1+b1a2 G1a1+b2a2 前者更优
(如果因为第一步后者更优,那么会推出 a2<b2 这个结论)

所以就对这个结论做了个简单的并不严谨的证明,贴代码=w=

#include<stdio.h>
#include<queue>

using namespace std;

typedef long long ll;

ll now,ans;
int n;

struct poi
{
    int a,b;
    inline void in(){scanf("%d%d",&a,&b);}
}p;

struct cmp1{bool operator()(const poi &b,const poi &a){return a.a<b.a;}};
struct cmp2{bool operator()(const poi &a,const poi &b){return a.b<b.b;}};
priority_queue<poi,vector<poi>,cmp1> A;
priority_queue<poi,vector<poi>,cmp2> B;

inline void cal(const poi &p)
{
    if((now-=p.a)<0) ans-=now,now=0;
    now+=p.b;
}

int main()
{
    scanf("%d",&n);
    while (n--)
    {
        p.in();
        if (p.a<p.b) A.push(p);
        else B.push(p);
    }
    while (!A.empty()) cal(A.top()),A.pop();
    while (!B.empty()) cal(B.top()),B.pop();
    printf("%lld",ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值