[JSOI2007]建筑抢修

[JSOI2007]建筑抢修

https://ac.nowcoder.com/acm/problem/20154

题解:

很明显的贪心题目,首先我们考虑按t2排序,因为我们先完成t2小的,那么这会比先完成t2大的留给后面人的时间更多。
但是这样会出现一个问题就是 由一个项目虽然她的t2很小,但是他的t1占用了后面太多的时间,使后面又任务不能及时完成。那么这时候我们就需要给程序填加一个反悔的功能:即当我们发现一个任务不能及时完成之后,这时其实我们可以用她和前面一个比他t1大的替换一下,那么此时我们的答案数仍然不变,但是我们的时间线确减小了。


代码:

#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define fi first
#define se second
#define pb push_back
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const  ll inf  = 0x3f3f3f3f3f3f3f3f;
const int mod  = 1e9+7;
const int maxn = 2e6 + 4;
const int N    = 5e3 + 5;
const double eps = 1e-6;
const double pi = acos(-1);
ll qpow(ll x,ll y){ll ans=1;x%=mod;while(y){ if(y&1) ans=ans*x%mod; x=x*x%mod; y>>=1;}return ans;}


struct node{
    ll t1,t2;
}a[maxn];
bool cmp(node a,node b){
    return a.t2<b.t2;
}
int n;
ll now,ans;
priority_queue<ll>q;
int main(){
    //freopen("input.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%lld%lld",&a[i].t1,&a[i].t2);
    }
    sort(a+1,a+1+n,cmp);
    ll now=0;
    for(int i=1;i<=n;i++) {
        if(now+a[i].t1<=a[i].t2) {
            ans++;
            q.push(a[i].t1);
            now+=a[i].t1;
        }
        else {
            ll top=q.top();q.pop();
            q.push(min(a[i].t1,top));
            now-=max(0*1ll,top-a[i].t1);
        }
    } 
    printf("%lld\n",ans);
}












































全部评论

相关推荐

头像
11-18 16:08
福州大学 Java
影流之主:干10年不被裁,我就能拿别人一年的钱了,日子有盼头了
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务