有N个任务需要执行,第i个任务计算时占R[i]个空间,而后会释放一部分,

最后储存计算结果需要占据O[i]个空间(O[i] < R[i])。





例如:执行需要5个空间,最后储存需要2个空间。


给出N个任务执行和存储所需的空间,问执行所有任务最少需要多少空间。





输入


第1行:1个数N,表示任务的数量。(2 <= N <= 100000)
第2 - N + 1行:每行2个数R[i]和O[i],分别为执行所需的空间和存储所需的空间。(1 <= O[i] < R[i] <= 10000)




输出




输出执行所有任务所需要的最少空间。




输入示例


20
14 1
2 1
11 3
20 4
7 5
6 5
20 7
19 8
9 4
20 10
18 11
12 6
13 12
14 9
15 2
16 15
17 15
19 13
20 2
20 1


输出示例


135





分析:

本题可以看做是计算机的程序任务,在执行时需要一些内存,执行完成后只需要少部分内存存储着。


该题在贪心策略上,可以采用先排序,再扫描。其关键在于排序的方式上。


依题意,用r表示执行占用的空间,o表示存储时占用的空间。那么每执行完一次任务会释放掉r-o的空间。


假设所有的任务满足 r == o ,那么最优解就是o之和。然而事实是 r > o ,那么每次一执行某个任务,


就会先多调用 r - o 的空间。如图:灰黑色条代表执行时占用的空间,黄色代表执行完后存储空间。


实际上,每次释放的r-o的大小(灰色部分),就是总是在多占用内存的部分,


最上面的红线就是最优解了。


所以我们以灰色部分按从大到小排序,就是最优策略。可以尽量降低红线的位置


贪心算法基础之任务执行顺序 51nod 贪心教程_C语言


,排序工作做好了,贪心就算完成一半了,最后只需扫描一遍,记录下红线的最高位置即可


代码:

#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;
int n;
struct node{
	int run;//执行时的内存占用 
	int min;//执行完后打的占用
	int away;//执行完此任务后释放掉的内存 
}r[100100];
bool cmp(node a,node b)
{
	return a.away>b.away;
}
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&r[i].run,&r[i].min);
			r[i].away=r[i].run-r[i].min;
		}
		sort(r,r+n,cmp);//按释放内存的大小从大到小排序
		int ram=0;
		int temp=0;//实时内存占用
		for(int i=0;i<n;i++)
		{
			temp+=r[i].run;
			if(ram<temp)
				ram=temp;
			temp-=r[i].away;//释放掉一部分
		}
		printf("%d\n",ram);
	}
	return 0;
}