• noip模拟赛 天天寄快递


    分析:并不是特别难的一道题,用到了贪心算法.

          首先可以明确的一点是我们要尽量偷贡献最大的数据,要先满足每一个公司的贡献都大于等于K,以这个作为首要条件.那么我们可以先把每个快递公司的快递按照贡献从大到小排序,每次选贡献最大的,满足要求了就考虑下一个快递公司,如果过程中用超过了s个或者处理完后发现还有快递公司没有满足要求就输出无解.

          上面只是满足了第一个要求,这时可能s个还没有用满,那么我们在按照贡献全体排一次序,看哪些没有用加上去就好了.

    中途犯了一个很愚蠢的错误:直接把vis数组赋值为i,其实这是不对的,每一个vis应该对应快递的ID,而不是排序后的i!

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int n, m, s, k;
    long long ans,tot, cnt, sum, cnt2;
    bool flag = false,can[200010];
    
    struct node
    {
        long long e, t;
        bool vis;
    }a[200010];
    
    bool cmp1(node a, node b)
    {
        if (a.e == b.e)
            return a.t < b.t; //实际上是看谁的贡献最大
        return a.e < b.e;
    }
    
    bool cmp2(node a, node b)
    {
        return a.t < b.t;
    }
    
    int main()
    {
        scanf("%d%d%d%d", &n, &m, &s, &k);
        for (int i = 1; i <= m; i++)
        {
            long long e, t;
            scanf("%lld%lld", &e, &t);
            if (2 - t < 0)
            {
                a[++tot].e = e;
                a[tot].t = 2 - t;
            }
        }
        sort(a + 1, a + 1 + tot, cmp1);
        if (a[tot].e < n)
        {
            printf("-23333333
    ");
            return 0;
        }
        for (int i = 1; i <= tot; i++)
        {
            if (can[a[i].e])
                continue;
            sum -= a[i].t;
            cnt++;
            a[i].vis = 1;
            if (cnt > s)
            {
                flag = 1;
                break;
            }
            if (sum >= k)
            {
                ans += sum;
                sum = 0;
                can[a[i].e] = 1;
            }
        }
        for (int i = 1; i <= n; i++)
            if (!can[i])
            {
                flag = 1;
                break;
            }
        if (flag)
            printf("-23333333
    ");
        else
        {
            sort(a + 1, a + tot + 1, cmp2);
            for (int i = 1; i <= tot; i++)
            {
                if (!a[i].vis)
                {
                    cnt++;
                    ans -= a[i].t;
                    if (cnt == s)
                        break;
                }
            }
            printf("%lld
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    查询死锁和处理死锁(SqlServer)
    日期函数(SqlServer)
    [Shell] echo/输出 中引用命令
    Github 团队协作基本流程与命令操作 图解git工作流程
    HTML 引入 CSS、JS 的三种方式
    JavaScript 字符串匹配 | JS 的正则用法 | 从后边匹配
    Sublime + Chrome 本地调试 CSS 选择器
    常用 CSS 选择器
    使用 Sublime 或其他编辑器调试 Tampermonkey 油猴脚本
    使用 chrome 扩展 Vimium 实现快捷键关闭其他标签页
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7581391.html
Copyright © 2020-2023  润新知