Codeforces Round #503 Div. 2 C - Elections 暴力+贪心

题意:ios

给定n个选民,m个政党,c++

而后n行表示每一个选民原本所选的政党p和让他选1号政党的花费spa

问:1号政党赢得选举(票数最多)的最小花费是多少code

 

思路:排序

首先咱们会往贪心方面想,可是由于涉及到当前选择哪一个人不必定是最优的,如样例二,可能选另外一个就能够代替以前选的两个而得到胜利;ci

可是咱们要是知道1号政党以多少票得到胜利,咱们就能够贪心的获得 其最小花费;it

其实能想到枚举1号政党赢得胜利的票数k就行,而后贪心的进行选择:io

把n我的按c排序,咱们从最大的开始选择,class

注意,这里选择的是不投给1号政党的人的p值,只要这个值尽可能大,那1号政党赢得胜利的花费就最小,sort

只要在选择的同时保证其余政党的票数<k  而且1号政党的票数>=k;

注意得是那些以前就选择1号政党的必须还得选择1号,因此遇到后跳过,最后用总花费减的时候也要减去这一部分

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const int maxn = 3000 + 7;
int n, m;
ll sum = 0, sum2 = 0, ans = 0;
int cnt[maxn];
P a[maxn];

ll solve(int k) {
    memset(cnt, 0, sizeof cnt);
    ll res = 0, num = 0;
    for(int i = n; i > 0; --i) {
        if(num + i <= k) break;
        if(a[i].second == 1) {
            num++; continue;
        }
        if(cnt[a[i].second]+1 < k) {
            res += a[i].first;
            cnt[a[i].second]++;
        }
        else {
            num++;
        }
    }
    return res;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> n >> m;
    for(int i = 1; i <= n; ++i) {
        ll p, c; cin >> p >> c;
        a[i] = P(c,p);
        sum += c;
        if(p == 1) sum2 += c;
    }
    sort(a+1,a+1+n);
    int m = n/2+1;
    for(int k = 1; k <= m; ++k) {
        ans = max(ans, solve(k));
    }
    printf("%lld\n", sum-sum2-ans);

    return 0;
}