second

CodeForces - 994B

题意:

有一群骑士,力量大的骑士可以杀力量小的骑士,并获得他的金币,但一个骑士最多只能杀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:

  1. 将骑士按力量从小到大排序,到第i个骑士的时候,前面的i-1个骑士他都可以击败,找出金币最多的k个。
  2. 用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;
}

 

posted @ 2021-01-30 17:03  彦辰kkkkk  阅读(130)  评论(0)    收藏  举报