题目描述
wlswls所在的王国有nn个居民(不包括wlswls),他们共有mm件神奇的宝物。
对于第ii件宝物,wlswls可以花费a_iai的金币把它从原来的主人那里买过来。
请问wlswls最少要准备多少金币,才能使他成为宝物最多的人(wlswls的宝物件数严格比其他所有人多)?
输入描述
第一行两个整数nn,mm。
接下来mm行,每行两个整数a_iai, c_ici,表示第ii件宝物属于居民c_ici,nxsnxs可以花费a_iai的代价得到它。
1 \leq n, m \leq 10001≤n,m≤1000
1 \leq a_i \leq 10000000001≤ai≤1000000000
1 \leq c_i \leq 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
思路:
通过分析数据范围,我们可以这样来求解:
枚举收购后每一个居民最大的宝物数x
然后对每一种x要付出的金钱取最小值即可。
细节:
我们可以先对每一个村民有的宝贝进行排序。
然后对于每一个村民,数量大于x的话,从小到大的依次收购,当数量小于等于x的时候,把所有的价格都加入一个小根堆中。
最后如果已经收购的数量小于等于数量x,即不满足一定大于所以居民的宝贝值。
那么从小根堆中取出我们花费最小的一些宝贝,让我们收购的数量大于x。
具体看代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #include <iomanip> #define ALL(x) (x).begin(), (x).end() #define rt return #define dll(x) scanf("%I64d",&x) #define xll(x) printf("%I64d\n",x) #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), '\0', sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define db(x) cout<<"== [ "<<x<<" ] =="<<endl; using namespace std; typedef long long ll; ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;} ll lcm(ll a, ll b) {return a / gcd(a, b) * b;} ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;} inline void getInt(int* p); const int maxn = 1000010; const int inf = 0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ vector<int> a[1030]; int n, m; ll check(int x) { ll res = 0ll; int cnt = 0; priority_queue<int, vector<int> , greater<int> > q; repd(i, 1, n) { int need = a[i].size() - x; for (auto y : a[i]) { if (need > 0) { res += y; need--; cnt++; } else { q.push(y); } } } while (cnt <= x) { ++cnt; res += q.top(); q.pop(); } return res; } int main() { //freopen("D:\\common_text\\code_stream\\in.txt","r",stdin); //freopen("D:\\common_text\\code_stream\\out.txt","w",stdout); gbtb; cin >> n >> m; ll x, c; repd(i, 1, m) { cin >> x >> c; a[c].pb(x); } repd(i, 1, n) { sort(ALL(a[i])); } int num = 0; ll ans = 1e18; repd(i, 0, m) { ans = min(ans, check(i)); } cout << ans << endl; return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ' ' || ch == '\n'); if (ch == '-') { *p = -(getchar() - '0'); while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 - ch + '0'; } } else { *p = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') { *p = *p * 10 + ch - '0'; } } }