题目描述
wls 所在的王国有 n 个居民(不包括 wls),他们共有 m 件神奇的宝物。
对于第 件宝物,wls 可以花费 的金币把它从原来的主人那里买过来。
请问 wls最少要准备多少金币,才能使他成为宝物最多的人(wls 的宝物件数严格比其他所有人多)?
输入描述
第一行两个整数 n,m。
接下来 m 行,每行两个整数 , , 表示第 件宝物属于居民 ,wls 可以花费 的代价得到它。
1≤n,m≤1000
1≤ai≤1000000000
1≤ci≤n
输出描述
一行一个整数表示答案。
思路:达成条件后,一定有某人的宝贝比夺宝人的宝贝少,暴力枚举除了夺宝人外的人中所能拥有宝贝数量的最大值(1~m)
借助优先队列实现。
代码:
#include<bits/stdc++.h>
using namespace std;
struct Pair
{
int first,second;
friend bool operator <(const Pair x,const Pair y)
{
if(x.first==y.first){return x.second > y.second;}
else{return x.first > y.first;}
}
};
priority_queue <Pair> G1[1005],V1;
vector<Pair>G[1005],V;
bool vis[1005];
int main()
{
//freopen("in","r",stdin);
int m,n;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,c;scanf("%d %d",&a,&c);
Pair u{a,i};
G1[c].push(u);V1.push(u);
}
for(int i=1;i<=n;i++)
while(!G1[i].empty()){ G[i].push_back(G1[i].top()); G1[i].pop();}
while(!V1.empty()){ V.push_back(V1.top()); V1.pop();}
long long minsum = 1e18;
for(int k=1;k<=m;k++)
{
long long sum=0,ans=0;
memset(vis,0, sizeof(vis));
for(int i=1;i<=n;i++)
{
int sizeya = G[i].size();
for(auto x:G[i]){if(sizeya<k)break; sum=sum+x.first; ans++; vis[x.second]=true; sizeya--;}
}
for(auto x:V)
{
if(ans>=k)break;
if(!vis[x.second]){sum+=x.first; ans++;}
}
if(sum<minsum)minsum=sum;
}
printf("%lld\n",minsum);
}