zoukankan      html  css  js  c++  java
  • UVALive 4850 Installations 贪心

    题目链接 

    题意

    工程师要安装n个服务,其中服务Ji需要si单位的安装时间,截止时间为di。超时会有惩罚值,若实际完成时间为ci,则惩罚值为max{0,ci-di}。从0时刻开始执行任务,问惩罚值最大的两个服务的惩罚值之和的最小是多少?

    分析

    乍一看似乎要二分,但实际上并不是。贪心来做,按di从小到大安排任务,当di相等时,让完成时间短的排前,这样安排任务一定时更优的,但是并不能满足题目的要求。于是需要从两个最大惩罚值的前面挑选一个任务,并将它放置在后面,然后更新答案即可。

    #include<cstdio>  
    #include<algorithm>  
    using namespace std;  
    #define maxn 510  
    struct Task{  
        int s, d;  
        bool operator <(const Task t) const{  
            if(t.d == d)  
                return s < t.s;  
            else  
                return d < t.d;    
        }  
    }T[maxn];  
    int pos, n;  
      
    int solve(int cur) {  
        int MAX1 = 0, MAX2 = 0, sum = 0;  
        for(int i = 0; i <= pos; i++) {  
            if(i == cur)  
                continue;     
            sum += T[i].s;  
            if(sum - T[i].d >= MAX2)   
                MAX2 = sum - T[i].d;  
            if(MAX2 > MAX1)  
                swap(MAX1,MAX2);  
        }  
      
        sum += T[cur].s;  
        if(sum - T[cur].d >= MAX2)  
            MAX2 = sum - T[cur].d;  
        if(MAX2 > MAX1)  
            swap(MAX1,MAX2);  
      
        for(int i = pos + 1; i < n; i++) {  
            sum += T[i].s;  
            if(sum - T[i].d >= MAX2)  
                MAX2 = sum - T[i].d;  
            if(MAX2 > MAX1)  
                swap(MAX1,MAX2);  
        }  
        return MAX2 + MAX1;  
    }  
      
    int main() {  
        int test;  
        scanf("%d",&test);  
        while(test--) {  
            scanf("%d",&n);  
            for(int i = 0; i < n; i++)  
                scanf("%d%d",&T[i].s, &T[i].d);  
            sort(T,T+n);  
      
            int cur = 0, MAX1 = 0, MAX2 = 0, t = 0;  
            for(int i = 0; i < n; i++) {  
                cur += T[i].s;  
                if(cur - T[i].d >= MAX2) {  
                    MAX2 = cur - T[i].d;  
                    pos = i;      
                }  
                if(MAX2 > MAX1)  
                    swap(MAX1,MAX2);  
            }  
      
            int ans = MAX1 + MAX2;  
            for(int i = 0; i < pos; i++)  
                ans = min(ans,solve(i));  
            printf("%d
    ",ans);  
        }  
        return 0;  
    }  
  • 相关阅读:
    本地发送博客
    0.查看Android framework源码
    flutter_5_深入_2_深入layout、paint流程
    flutter_5_深入_1_深入widget树和构建流程
    flutter_5_深入_0_每帧的处理流程简介
    蓝牙基础
    Android低功耗蓝牙开发
    flutter2_widget_3布局类组件1
    flutter2_widget_1简介
    Android gradle Plugin
  • 原文地址:https://www.cnblogs.com/fht-litost/p/8912083.html
Copyright © 2011-2022 走看看