1019A Elections(暴力列舉+思維)
阿新 • • 發佈:2018-12-14
Elections 題 意:有n個選民,m個政黨,每個選民都有自己要投的政黨,和可以被賄賂的金額,。現在1號政黨想贏的這場選舉,問最少需要花費多少金錢。 資料範圍: 輸入樣例:
1 2
1 100
輸出樣例:
0
輸入樣例:
5 5
2 100
3 200
4 300
5 400
5 900
輸出樣例:
500
思 路:n,m只有3000,所以可以去列舉最後穩贏的選票。其實也就是這一個地方難想一點。其他地方都很好寫的。一點點思維。 收 獲:增強了列舉的意識了吧。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cmath>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<11
#define IN freopen("input.txt","r",stdin)
#define debug(x) cout<< #x <<" = "<< (x) <<endl;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 3e3+5;
int vis[maxn];
int n,m;
struct node {
ll p,c,id;
bool operator<(const node &_p)const {
return c<_p.c;
}
} a[maxn];
vector<node> vec,vec1;
int mp[maxn];
int mp1[maxn];
ll solve(int x) {
memset(vis,0,sizeof(vis));
for(int i=1; i<=m; i++)mp1[i]=mp[i]
vec.clear();
vec1.clear();
for(int i=1; i<=n; i++) {
if(a[i].p == 1)continue;
if(mp1[a[i].p] >= x) {
vec.push_back(node{a[i].p,a[i].c,i});
} else {
vis[i] = 1;
vec1.push_back(node{a[i].p,a[i].c,i});
}
}
sort(vec.begin(),vec.end());
ll sum = 0;
int res = mp1[1];
for(int i=0; i<vec.size(); i++) {
ll temp1 = vec[i].p,temp2 = vec[i].c,id = vec[i].id;
if(mp1[temp1] < x) {
if(!vis[id]) {
vec1.push_back(node{temp1,temp2,id});
}
continue;
}
sum += temp2;
mp1[temp1]--;
res++;
}
sort(vec1.begin(),vec1.end());
for(int i=0; i<vec1.size(); i++) {
if(res<x) {
res++;
sum+=vec1[i].c;
} else {
break;
}
}
if(res!=x) return INF;
else return sum;
}
int main() {
#ifdef LOCAL
IN;
#endif
scanf("%d %d",&n,&m);
for(int i=1; i<=n; i++) {
scanf("%lld %lld",&a[i].p,&a[i].c);
mp[a[i].p]++;
}
ll ans = INF;
for(int i=mp[1]; i<=n; i++) {
ans = min(solve(i),ans);
}
printf("%lld\n",ans);
return 0;
}