Description
你有许多电脑,它们的硬盘用不同的文件系统储存数据。你想要通过格式化来统一文件系统。格式化硬盘可能使它的容量发生变化。为了格式化,你需要买额外的硬盘。当然,你想要买容量最小的额外储存设备以便省钱。你可以按任意顺序格式化硬盘。格式化之前,你要把该硬盘上所有数据移到一个或更多的其他硬盘上(可以分割数据)。格式化后,该硬盘可以立刻开始使用。你没有必要把数据放到它原来所在的硬盘上。数据也可以被放到你额外买的硬盘上。举个例子,假设你有
4
个硬盘
第一行一个数
n(1≤n≤1,000,000)
,表示你的硬盘数。接下来
n
行,每行两个数
Output
输出如果要格式化所有硬盘,你最少需要购买多少额外空间 (GB) 。
Solution
先说一个结论:
先对所有
a<b
的硬盘按
a
升序做,再把剩下硬盘按
首先对于 a 升序部分,考虑只在需要的时候买空间,那么对于一个硬盘,它格式化后肯定能提供更多的空间(减少下一个硬盘启动格式化所需的空间)。并且,启动某个硬盘的格式化的时候,购买的额外空间量一定小于直接开启它所需空间量。
对于剩下部分,考虑对于两个硬盘,分别为
第一步:
G1−a1
和
G2−a2
无法比较
第二步:
G1−a1+b1−a2
和
G1−a1+b2−a2
前者更优
(如果因为第一步后者更优,那么会推出
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);
}