1. 程式人生 > >1019A Elections(暴力列舉+思維)

1019A Elections(暴力列舉+思維)

Elections 題 意:有n個選民,m個政黨,每個選民都有自己要投的政黨,和可以被賄賂的金額,pi,cipi,ci。現在1號政黨想贏的這場選舉,問最少需要花費多少金錢。 資料範圍: 1<=n,m<=30001<=n,m<=3000 1<=pi<=m1<=pi<=m 1<=ci<=1e91<=ci<=1e9 輸入樣例:

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; }