链接
http://codeforces.com/contest/1020/problem/C
题解
我一向拿贪心题没办法…
枚举2…m中的最大值
lim
l
i
m
,每次强制把那些票数多于
lim
l
i
m
的党派取最便宜的一部分人收买
售卖完了之后如果
1
1
的票数还是不大于,就从剩下的人里面选最小的一部分人收买,使得
1
1
的票数超过
对于枚举的每一个
lim
l
i
m
,计算最小开销,然后取个
min
m
i
n
就做完了
话说这个
lim
l
i
m
的枚举是不是满足三分的条件??(欢迎评论区指出
代码
//贪心
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cmath>
#define cl(x,y) memset(x,y,sizeof(x))
#define int_inf 0x3f3f3f3f
#define ll_inf (1ll<<60)
#define eps 1e-8
#define maxn 3010
#define ll long long
using namespace std;
struct people
{
ll p, c;
}peo[maxn];
bool operator<(people p1, people p2){return p1.c<p2.c;}
ll N, M, now[maxn], mark[maxn], cnt[maxn];
ll read(ll x=0)
{
char c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-48;
return f*x;
}
ll work(ll lim)
{
ll i, t, cost=0;
for(i=1;i<=M;i++)now[i]=0;
for(i=1;i<=N;i++)now[peo[i].p]++, mark[i]=peo[i].p==1;
for(i=1;i<=N;i++)if(now[peo[i].p]>lim and !mark[i])mark[i]=1, cost+=peo[i].c, now[peo[i].p]--, now[1]++;
for(i=1;i<=N and now[1]<=lim;i++)if(!mark[i])cost+=peo[i].c, now[1]++;
return cost;
}
void init()
{
ll i;
N=read(), M=read();
for(i=1;i<=N;i++)peo[i].p=read(), peo[i].c=read();
sort(peo+1,peo+N+1);
}
int main()
{
ll ans=ll_inf, i;
init();
for(i=0;i<=N;i++)ans=min(ans,work(i));
printf("%I64d",ans);
return 0;
}