zoukankan      html  css  js  c++  java
  • noip模拟赛 业务办理

    【问题描述】
    在银行柜台前,有 n 个顾客排队办理业务。 队伍中从前往后,第 i 位顾客办理业务需要
    ti 分钟时间。 一位顾客的等待时间定义为:队伍中在他之前的所有顾客和他自己的办理业务
    时间的总和。第 i 位顾客有一个最长等待时间 di,如果超过了时间 di, 业务还没有办理完成,
    那么这位顾客就会觉得不满意。 具体来说, 假设第 i 位顾客的等待时间为 fi,若 fi > di, 则这
    位顾客的不满意度为 fi-di,否则不满意度为 0
    你作为银行里的职员,需要安排这 n 位顾客的初始排队顺序,使得不满意度最大的那位
    顾客不满意度最小。
    【输入】
    输入的第 1 行包含一个正整数 n,表示顾客的数量。
    输入的第 2 行包含 n 个正整数,第 i 个数表示 ti, 单位为分钟。
    输入的第 3 行包含 n 个正整数,第 i 个数表示 di, 单位为分钟。
    【输出】
    输出包含 1 个整数,表示最大不满意度的最小值。
    【输入输出样例 1

    transact.in transact.out
    3
    5 8 10
    11 15 13
    8


    见选手目录下的 transact / transact1.in transact / transact1.out
    【输入输出样例 1 说明】

    排队顺序 1 3 2
    业务办理时间 5 10 8
    等待时间 5 15 23
    最长等待时间 11 13 15
    不满意度 0 2 8


    最大不满意度为 8。 这是最大不满意度能达到的最小值。
    【数据规模与约定】
    对于 50%的数据, n≤10
    对于 70%的数据, n≤1,000
    对于 100%的数据, n≤100,0001≤ti≤1040≤di≤109

    分析:看到最大值最小,本能的反应就是二分答案,但是二分完后又该怎么check呢?还不是要贪心地找一种排队顺序......所以根本就不需要二分嘛,直接贪心.这种排队的贪心一般都是按照某个量来排序,如果按每个人所花的时间来排序是肯定不对的,因为很有可能最后花的时间最长的那个人的最长等待时间最短.那就按照最长等待时间来排序吧,事实证明这是对的.

          要怎么证明它呢?排序的贪心问题证明的一般方法是交换相邻的两个,假设已经按照贪心策略排序好了,第i个人的办理业务时间是a,最长等待时间是b,第i+1个人的办理业务时间是c,最长等待时间是d,1到i-1个人办理业务时间的总和是x.当第i个人在第i+1个人前面时,ans = max{x+a-b,x+a+c-d},当第i+1个人在第i个人前面时,ans = max{x+c-d,x+c+a-b},由于x+c+a-b > x+a+c-d,x+c+a-b>x+a-b,所以后面一种方式一定没有前一种优,所以按照最长等待时间排序是对的.

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int n, ans, sum;
    
    struct node
    {
        int t, d;
    }e[100010];
    
    bool cmp(node a, node b)
    {
        return a.d < b.d;
    }
    
    int main()
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d", &e[i].t);
        for (int i = 1; i <= n; i++)
            scanf("%d", &e[i].d);
        sort(e + 1, e + 1 + n, cmp);
        for (int i = 1; i <= n; i++)
        {
            sum += e[i].t;
            if (sum - e[i].d > ans)
                ans = sum - e[i].d;
        }
    
        printf("%d
    ", ans);
        return 0;
    }

     

  • 相关阅读:
    【复习】数据库维护-索引语法
    C# 以管理员身份运行WinForm程序
    Postgresql死锁处理
    401 Not Authorized For MSDEPLOY‏ (msdeployAgentService)
    GIT使用指南
    redis使用指南
    nginx使用指南
    DB2日常维护常用命令
    AIX常用命令总结
    C语言+嵌入式SQL+DB2开发经验总结
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7741794.html
Copyright © 2011-2022 走看看