题意:
有 n个人,m个党派,第i个人开始想把票投给党派pi,而如果想让他改变他的想法需要花费ci元。你现在是党派1,问你最少花多少钱使得你的党派得票数大于其它任意党派。
n,m<3000
思路:
枚举“除了党派1之外其他党派最多有的票的数量”,贪心一下即可
坑点:
1.爆int
2.inf太小,要设成0x3f3f3f3f3f3f3f3f
3.sort忘了从第一个开始排(被Wa7支配)
#include<iostream> #include<iomanip> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #include<functional> #include<list> #define fst first #define sc second #define pb push_back #define mp(a,b) make_pair(a,b) #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 #define lowbit(x) ((x)&(-x)) #pragma Gcc optimize(2) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const int maxn = 10000 + 100; const int maxm = 5e3 + 100; const double eps = 1e-10; const int inf = 0x3f3f3f3f; const double pi = acos(-1.0); int scan(){ int res=0,ch,flag=0; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return flag?-res:res; } //int vis[maxn]; struct vt{ int id; int p; ll c; }v[maxn]; int num[maxn]; int cnt[maxn]; int vis[maxn]; /*bool cmp(vt a, vt b){ if(a.p==1)return false; if(b.p==1)return true; if(num[a.id] == num[b.id]){ return a.c < b.c; } else return num[a.id]<num[b.id]; }*/ bool cmp(vt a, vt b){ if(a.p==1)return false; if(b.p==1)return true; return a.c < b.c; } int main(){ int n, m; scanf("%d %d", &n, &m); //mem(vis, 0); mem(num, 0); for(int i = 1; i <= n; i++){ int p, c; scanf("%d %lld",&v[i].p, &v[i].c); v[i].id = i; num[v[i].p]++; } ll ans = 0x3f3f3f3f3f3f3f3f; sort(v+1, v+1+n, cmp); for(int i = 0; i < n; i++){ ll tmp = 0; mem(vis, 0); for(int j = 1; j <= m ;j++){ cnt[j] = num[j]; } for(int j = 1; j <= n && v[j].p != 1; j++){ if(cnt[v[j].p] > i){ cnt[1]++; cnt[v[j].p]--; tmp += v[j].c; vis[j] = 1; } } if(cnt[1] <= i){ for(int j = 1; j <= n; j++ ){ if(cnt[1]>i)break; if(!vis[j]){ tmp += v[j].c; cnt[1]++; } } } if(cnt[1]>=i)ans = min(tmp, ans); //printf("%lld %d ", tmp, cnt[1]); } printf("%lld", ans); return 0; }