• 【BZOJ1029】[JSOI2007] 建筑抢修(堆优化贪心)


    点此看题面
    大致题意: 有N个受到严重损伤的建筑,对于每个建筑,修好它需要(T1)秒,且必须在(T2)秒之前修完((T1)(T2)不是固定值),问你最多能修好几个建筑。

    题解

    一看到这题,就能想到一个贪心的做法。

    但是,裸贪心显然是不能过的,如果加上一个堆优化,就能够水过此题。

    我们可以把修好每个建筑所需的时间放入大根堆中存储。对于每一个建筑,若能在规定时间内修好,则将(ans)(1),否则比较修好它所需的时间与堆顶元素的大小,若修好它所需的时间更少,则用其替换堆顶,此时(ans)不变。

    代码

    #include<bits/stdc++.h>
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define N 150000
    using namespace std;
    int n;
    struct Building
    {
    	int a,t;
    }s[N+5];
    priority_queue<int> h;
    inline char tc()
    {
    	static char ff[100000],*A=ff,*B=ff;
    	return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
    	x=0;char ch;
    	while(!isdigit(ch=tc()));
    	while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
    }
    inline void write(int x)
    {
    	if(x>9) write(x/10);
    	putchar(x%10+'0');
    }
    bool cmp(Building x,Building y)
    {
    	return x.t<y.t;
    }
    int main()
    {
    	register int i;
    	for(read(n),i=1;i<=n;++i) read(s[i].a),read(s[i].t);
    	sort(s+1,s+n+1,cmp);//将每一个建筑按无法重修的时间从小到大排序
    	int tot=0,ans=0;//tot表示当前时间
    	for(i=1;i<=n;++i)
    	{
    		if(s[i].t<tot+s[i].a)//判断时间是否来得及
    		{
    			if(s[i].a<h.top()) tot-=h.top(),h.pop(),h.push(s[i].a),tot+=s[i].a;//如果来不及,比较其与堆顶元素的大小,若其更小,则弹出堆顶,更新当前时间,并将修好该建筑所需时间加入堆中
    		}
    		else h.push(s[i].a),tot+=s[i].a,++ans;//如果来得及,ans加1,并将修好该建筑所需时间加入堆中
    	}
    	return write(ans),0;
    }
    
  • 相关阅读:
    hdu 2050 折线分割平面 递推
    hdu 2044 一只小蜜蜂 斐波那契数列 递推
    hdu 2018 母牛的故事 递推
    hdu 2084 数塔 dp 动态规划
    Linux 常用协议结构体及详解
    【ArcEngine入门与提高】Element(元素)、Annotation(注记)旋转
    AO总结10:MapControl控件
    esriControlsMousePointer 控制鼠标指针
    图解VS2010打包全过程(转)
    ArcEngine中打开各种数据源(WorkSpace)的连接(转)
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ1029.html
Copyright © 2020-2023  润新知