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 fuck {
	int id;ll v;
	bool operator <(const fuck a)const{
		return this->v < a.v;
	}
	bool operator >(const fuck a)const {
		return this->v > a.v;
	}
};
struct fucker {
	int from; ll v;
}vul[1005];
bool cmp(fucker a, fucker b) {
	return a.v < b.v;
}
vector<fuck>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(fuck{ 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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值