zoukankan      html  css  js  c++  java
  • CCPC-Wannafly Winter Camp Day1 (Div2, onsite) 夺宝奇兵

    题目描述

     

    wlswls所在的王国有nn个居民(不包括wlswls),他们共有mm件神奇的宝物。

    对于第ii件宝物,wlswls可以花费a_iai的金币把它从原来的主人那里买过来。

    请问wlswls最少要准备多少金币,才能使他成为宝物最多的人(wlswls的宝物件数严格比其他所有人多)?

     
     

    输入描述

     

    第一行两个整数nn,mm。

    接下来mm行,每行两个整数a_iaic_ici,表示第ii件宝物属于居民c_icinxsnxs可以花费a_iai的代价得到它。

    1 leq n, m leq 10001n,m1000

    1 leq a_i leq 10000000001ai1000000000

    1 leq c_i leq n1cin

    输出描述

     

    一行一个整数表示答案。

    样例输入 1 

    4 11
    10 1
    1 1
    10 2
    1 2
    10 3
    1 3
    15 4
    15 4
    15 4
    15 4
    15 4

    样例输出 1

    28


    思路:
    通过分析数据范围,我们可以这样来求解:
    枚举收购后每一个居民最大的宝物数x
    然后对每一种x要付出的金钱取最小值即可。
    细节:
    我们可以先对每一个村民有的宝贝进行排序。
    然后对于每一个村民,数量大于x的话,从小到大的依次收购,当数量小于等于x的时候,把所有的价格都加入一个小根堆中。
    最后如果已经收购的数量小于等于数量x,即不满足一定大于所以居民的宝贝值。
    那么从小根堆中取出我们花费最小的一些宝贝,让我们收购的数量大于x。
    具体看代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
    inline void getInt(int* p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    vector<int> a[1030];
    int n, m;
    ll check(int x)
    {
        ll res = 0ll;
        int cnt = 0;
        priority_queue<int, vector<int> , greater<int> > q;
        repd(i, 1, n)
        {
            int need = a[i].size() - x;
            for (auto y : a[i])
            {
                if (need > 0)
                {
                    res += y;
                    need--;
                    cnt++;
                } else {
                    q.push(y);
                }
            }
        }
        while (cnt <= x)
        {
            ++cnt;
            res += q.top();
            q.pop();
        }
        return res;
    }
    int main()
    {
        //freopen("D:\common_text\code_stream\in.txt","r",stdin);
        //freopen("D:\common_text\code_stream\out.txt","w",stdout);
        gbtb;
        cin >> n >> m;
        ll x, c;
        repd(i, 1, m)
        {
            cin >> x >> c;
            a[c].pb(x);
        }
        repd(i, 1, n)
        {
            sort(ALL(a[i]));
        }
        int num = 0;
        ll ans = 1e18;
        repd(i, 0, m)
        {
            ans = min(ans, check(i));
        }
        cout << ans << endl;
    
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    正则判断手机号是不是11位
    jQuery, js 验证两次输了密码的一相同
    数据库读取图片
    使用 jQuery 修改 css 中带有 !important 的样式属性
    PHP去掉最后一个字符
    按钮
    js 实现两种99乘法表
    PHP 各种循环
    thinkphp的空控制器和空操作以及对应解决方法
    ThinkPHP框架知识
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10897434.html
Copyright © 2011-2022 走看看