second
题意:
有一群骑士,力量大的骑士可以杀力量小的骑士,并获得他的金币,但一个骑士最多只能杀k个人,问每个骑士可以获得的最大金币数是多少,
思路:
刚开始做的时候想的是先把所有人按照金币的数目排序,然后两重循环从后往前数,如果这个骑士遇到比他力量小的骑士就杀掉,直到杀掉k个骑士。最后得出来的样例答案都是过的,但最后提交就是过不了,原因不明,可能时间复杂度是O(n^2)太高了吧。
之后补题的时候看这个题网上用的都是队列和mutiset,但我都不会QWQ,所以借这个题学习一下mutiset这个数据结构。
c++语言中,multiset是<set>库中一个非常有用的类型,它可以看成一个序列,插入一个数,删除一个数都能够在O(logn)的时间内完成,而且他能时刻保证序列中的数是有序的,而且序列中可以存在重复的数。具体看网址
(https://blog.csdn.net/sodacoco/article/details/84798621ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161199424416780264095103%252522%25252C%252522scm%252522%25253A%25252220140713.130102334..%252522%25257D&request_id=161199424416780264095103&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-84798621.pc_search_result_before_js&utm_term=multiset)
这是刚开始的思路:
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 struct knight 8 { 9 long long power; 10 long long coin; 11 long long sum; 12 }a[5000010]; 13 14 bool cmp(knight x , knight y) 15 { 16 return x.coin < y.coin; 17 } 18 19 int main() 20 { 21 int n , k; 22 cin >> n >> k; 23 for(int i = 0 ; i < n ; i ++ ) cin >> a[i].power; 24 for(int i = 0 ; i < n ; i ++ ) cin >> a[i].coin , a[i].sum = a[i].coin; 25 26 sort(a , a + n , cmp); 27 for(int i = 0 ; i < n ; i ++ ) 28 { 29 int cnt = 0; 30 for(int j = n - 1 ; j >= 0 ; j -- ) 31 { 32 if(a[i].power > a[j].power) 33 { 34 a[i].sum += a[j].coin; 35 cnt ++ ; 36 } 37 if(cnt == k) break; 38 } 39 } 40 for(int i = 0 ; i < n - 1 ; i ++ ) 41 cout << a[i].sum << ' '; 42 return 0; 43 }
mutiset:
- 将骑士按力量从小到大排序,到第i个骑士的时候,前面的i-1个骑士他都可以击败,找出金币最多的k个。
- 用multiset存金币最多的k个骑士的金币数,如果多余k个,则删除金币数最小的,直到只有k个数字。
#include <iostream> #include <cstring> #include <algorithm> #include <set> using namespace std; struct knight { long long power; long long coin; long long sum; int id; }a[5000010]; bool cmp(knight x , knight y) { return x.power < y.power;//按力量从小到大排序 } long long ans[500010]; int main() { int n , k; cin >> n >> k; for(int i = 0 ; i < n ; i ++ ) cin >> a[i].power, a[i].id = i; for(int i = 0 ; i < n ; i ++ ) cin >> a[i].coin ; sort(a , a + n , cmp); multiset <int> s;//存第i个骑士可以击败的不超过k个骑士的金币数 for(int i = 0 ; i < n ; i ++ ) { ans[a[i].id] = a[i].coin; for(auto t:s) ans[a[i].id] += t; s.insert(a[i].coin);//插入 while(s.size() > k)//如果将第i个骑士的金币数插入之后大于k个数字,就删除到只有k个 s.erase(s.begin()); //这几步就相当于是插入一个大的然后删除一个小的 } for(int i = 0 ; i < n ; i ++ ) cout << ans[i] << ' '; return 0; }

浙公网安备 33010602011771号