题意: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; }