题目大意

给你 nn 个硬盘,第 ii 个硬盘原来有 aia_i 的内存,但是在转化格式之后内存就变成了 bib_i。在转化格式的时候,全部的资料都需要转移到其他空间,如果空间不够用就可以额外申请空间。在最开始的时候每个硬盘都装满了,求额外申请的空间的最小值。

思路

首先所有的硬盘一共与三种分类:ai<bia_i<b_iai=bia_i=b_iai>bia_i>b_i

因为第 22 类对于答案没有影响,所以为了便于处理,我们将第 22 类归入第一类,即 aibia_i\le b_iai>bia_i>b_i

应该优先处理第 11 类,因为在修改之后剩余的空间是在增加的。

对于第 11 类,应该按 aia_i 从小到大处理更优,证明如下:

假设有 22 块硬盘分别是 (a1,b1)(a_1,b_1)(a2,b2)(a_2,b_2)

如果 $b_1\ge a_2 $:先处理 a1a_1 再处理 a2a_2,需要的代价是 a1a_1;先处理 a2a_2 再处理 a1a_1,需要的代价是 a2a_2。因为 a1a2a_1\le a_2,所以先处理第 11 块更优。

如果 b1<a2b_1< a_2:先处理 a1a_1 再处理 a2a_2,需要的代价是 a1+a2b1a_1+a_2-b_1;先处理 a2a_2 再处理 a1a_1,需要的代价是 a2a_2。因为a1+a2b1a2a_1+a_2-b_1\le a_2,所以先处理第 11 块更优。

对于第 22 类,应该按 bib_i 从大到小处理更优,证明如下:

假设有 22 块硬盘分别是 (a1,b1)(a_1,b_1)(a2,b2)(a_2,b_2)

如果 $b_1\ge a_2 $:先处理 a1a_1 再处理 a2a_2,需要的代价是 a1a_1;先处理 a2a_2 再处理 a1a_1,需要的代价是 a2+a1b2a_2+a_1-b_2。因为 a1a2+a1b2a_1\le a_2+a_1-b_2,所以先处理第 11 块更优。

如果 b1<a2b_1< a_2:先处理 a1a_1 再处理 a2a_2,需要的代价是 a1+a2b1a_1+a_2-b_1;先处理 a2a_2 再处理 a1a_1,需要的代价是 a2+a1b2a_2+a_1-b_2。因为a1+a2b1a2+a1b2a_1+a_2-b_1\le a_2+a_1-b_2,所以先处理第 11 块更优。

所以,排序之后模拟整个过程,时间复杂度 O(nlogn)O(n\log n)

AC Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int n,c1,c2,ans,cnt;
struct node{int a,b;}s1[N],s2[N];
bool cmp1(node x,node y){return x.a<y.a;}
bool cmp2(node x,node y){return x.b>y.b;}
signed main(){
	cin>>n;
	for(int i=1,a,b;i<=n;i++){
		cin>>a>>b;
		if(a<b) s1[++c1]={a,b};
		else s2[++c2]={a,b};
	}sort(s1+1,s1+1+c1,cmp1),sort(s2+1,s2+1+c2,cmp2);
	for(int i=1;i<=c1;i++){
		if(cnt<s1[i].a) ans+=(s1[i].a-cnt),cnt=0;
		else cnt-=s1[i].a;
		cnt+=s1[i].b;
	}for(int i=1;i<=c2;i++){
		if(cnt<s2[i].a) ans+=(s2[i].a-cnt),cnt=0;
		else cnt-=s2[i].a;
		cnt+=s2[i].b;
	}cout<<ans<<endl;
	return 0;
}