CCPC-Wannafly Winter Camp 夺宝奇兵
题目描述
wls所在的王国有n个居民(不包括wls),他们共有m件神奇的宝物。
对于第ii件宝物,wls可以花费ai的金币把它从原来的主人那里买过来。
请问wls最少要准备多少金币,才能使他成为宝物最多的人(wls的宝物件数严格比其他所有人多)?
输入描述
第一行两个整数n,m。
接下来mm行,每行两个整数ai, ci,表示第i件宝物属于居民ci,可以花费ai的代价得到它。
10001≤n,m≤1000
10000000001≤ai≤1000000000
n1≤ci≤n
输出描述
一行一个整数表示答案。
样例输入 1
4 11 10 1 1 1 10 2 1 2 10 3 1 3 15 4 15 4 15 4 15 4 15 4
样例输出 1
28
枚举最后要买n个,然后看看每个居民如果持有数n大,那就把他多出来的数量从小到大买他的宝物,最后加起来之前必须要买的数量如果小于n,再从所有的自己没买的宝物中从小到大买够。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct *** {
int id;ll v;
bool operator <(const *** a)const{
return this->v < a.v;
}
bool operator >(const *** a)const {
return this->v > a.v;
}
};
struct ***er {
int from; ll v;
}vul[1005];
bool cmp(***er a, ***er b) {
return a.v < b.v;
}
vector<***>G[1005];
bool use[1005];
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> vul[i].v >> vul[i].from;
}
sort(vul + 1, vul + m + 1, cmp);
for (int i = 1; i <= m; i++) {
G[vul[i].from].push_back(***{ i,vul[i].v });
}
for (int i = 1; i <= n; i++)
sort(G[i].begin(), G[i].end());
ll res = 0x3f3f3f3f3f3f3f3f;
for (int i = 1; i <= m; i++) {
memset(use, 0, sizeof use);
ll sum = 0, num = 0;
for (int j = 1; j <= n; j++) {
if (G[j].size() < i)continue;
for (int k = 0; k <= G[j].size() - i; k++) {
sum += G[j][k].v;
num++; use[G[j][k].id] = 1;
}
}
if (num < i) {
for (int k = 1; k <= m; k++) {
if (use[k])continue;
sum += vul[k].v;
num++;
if (num >= i)break;
}
}
res = min(res, sum);
}
cout << res << "\n";
return 0;
}