BZOJ 1029: [JSOI2007]建筑抢修

http://www.lydsy.com/JudgeOnline/problem.php?id=1029

/*
* 题目:
* 每个任务需要ai时间完成,并且需要在时间bi或之前完成,问如何安排任务完成顺序,使得完成
* 任务的数量最多
*
* 分析:
* 贪心,先对期限排序,然后用最大堆维护需要完成的时间ai
* 1.当now + ai <= bi时,ans + 1 ,更新now,把ai插入到堆中
* 2.当now + ai > bi时,若堆的最大元素大于ai时,将该元素(aj,bj)替换为ai,得到的序列答案
* 不会减少。因为替换之后,时间期限bi必定大于bj,所以可以完成该任务,另外替换之后,所需的
* 时间减少了,所以替换是正确的。
*
* */

#include <cstdio>

#include <cstring>

#include <iostream>

#include <algorithm>



using namespace std;



const int X = 150005;



#define debug puts("here");



struct Heap{

	int a[X];

	int s;



	void insert(int x){

		a[++s] = x;

		for(int i=s;i>1;i>>=1){

			if(a[i] > a[i>>1])

				swap(a[i],a[i>>1]);

			else

				break;

		}

	}



	void down(int x){

		a[1] = x;

		int i = 1;

		int j = 2;

		while(j<=s){

			if(j+1<=s && a[j+1]>a[j])

				j ++;

			if(a[j]>a[i]){

				swap(a[i],a[j]);

				i = j;

				j <<= 1;

			}

			else

				break;

		}

	}



	void init(){

		memset(a,0,sizeof(a));

		s = 0;

	}



	void display(){

		for(int i=1;i<=s;i++)

			cout<<a[i]<<" ";

		cout<<endl;

	}

}heap;



struct node{

	int last,time;

	friend bool operator < (node a,node b){

		return a.time < b.time || (a.time==b.time&&a.last<b.last);

	}

}p[X];



int main(){

	int n;

	while(cin>>n){

		for(int i=0;i<n;i++)

			scanf("%d%d",&p[i].last,&p[i].time);

		

		sort(p,p+n);

		heap.init();

		int now = 0;

		int ans = 0;



		for(int i=0;i<n;i++){

			if(now+p[i].last<=p[i].time){

				ans ++;

				now += p[i].last;

				heap.insert(p[i].last);

			}

			else if(heap.a[1]>p[i].last){

				now -= heap.a[1]-p[i].last;

				heap.down(p[i].last);

			}

			//heap.display();

		}

		cout<<ans<<endl;

	}



	return 0;

}

  

你可能感兴趣的:(2007)