zoukankan      html  css  js  c++  java
  • Codeforces Round #664 (Div. 2) D. Boboniu Chats with Du

    传送门:cf1395D

    题意

    给定一个长度为n的数组a[i]为当天说话的有趣值,如果a[i]>m,那么在 i 之后有d天不能说话。否则可以每天都说话。找到一个排列使得n天有趣值总和最大,问有趣值总和的最大值是多少。

    题解

    很明显用贪心。先取>m的有趣值直到取不下。根据样例1的解释可以看出将一个大于m的值放在最后,前边放<m的会更优,所以此时有两种情况,如果取了的p个大于m的值p*(d+1)(p个大于m的总共占了多少天)大于n,那么就要找到最后一个能说话的天后不能说话的天数,即d-(p*(d+1)-n),然后可以加上<m最大的前d-(p*(d+1)-n)天,相当于把这段放在最后说话的那天前边。如果p*(d+1)<=n,剩下的位置就可以直接由大到小放<m的有趣值,因为最后一个>m的值后边也有d天不能说话,所以也将最后一个>m的值移到最后,相当于再加上d个<m的值,和前边的做法一样。然后就可以开始用<m的段替换>m的段,如果长度为d+1的<m的剩余的值和的最大值比所取的>m的值的最小值大,那么就可以直接用这一段替代>m的那一段,直到没有这样的段可以替代位置。

    说的绕绕的,当时想的就绕绕的,代码还行,好像是有更简便的做法的。

    代码

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 
     5 ll a[100100];
     6 ll b[100100];
     7 
     8 ll cmp(ll x,ll y)
     9 {
    10     return x>y;
    11 }
    12 
    13 int main()
    14 {
    15     ios::sync_with_stdio(false);
    16     cin.tie(0);
    17     cout.tie(0);
    18     ll n,m,d;
    19     cin>>n>>d>>m;
    20     for(ll i=0;i<n;i++) cin>>a[i];
    21     sort(a,a+n,cmp);
    22     ll ans=0;
    23     ll k=0,p=0,q=0;
    24     for(ll i=0;i<n;i++){
    25         if(a[i]<=m) b[k++]=a[i];
    26     }
    27     ll cnt=0;
    28     for(ll i=0;i<n-k;i++){
    29         if(cnt>=n) break;
    30         cnt++;
    31         ans+=a[i];
    32         cnt+=d;
    33         p++;
    34     }
    35     p--;
    36     for(ll i=cnt;i<n;i++) ans+=b[q++];
    37     if(k==0) {cout<<ans<<endl;return 0;}
    38     if(cnt>n){
    39         ll res=0;
    40         ll pp=cnt-n;
    41         pp=d-pp;
    42         for(ll i=q;i<min(q+pp,k);i++) res+=b[i];
    43         q+=pp;
    44         ans+=res;
    45     }
    46     else{
    47         ll res=0;
    48         for(ll i=q;i<min(q+d,k);i++) res+=b[i];
    49         q+=d;
    50         ans+=res;
    51     }
    52     while(q<k&&p>=0){
    53         ll res=0;
    54         for(ll i=q;i<min(q+d+1,k);i++) res+=b[i];
    55         if(res>a[p]) ans-=a[p],ans+=res,p--;
    56         else break;
    57         q+=d+1;
    58     }
    59     cout<<ans<<endl;
    60     return 0;
    61 }
  • 相关阅读:
    数据库
    Activity组件
    view,视图组件
    360导航板式
    service音乐播放
    service
    音乐播放器组件
    获取时间字符串
    JDK服务器存储
    数据库_黑名单练习_完善服务广播
  • 原文地址:https://www.cnblogs.com/lilibuxiangtle/p/13494819.html
Copyright © 2011-2022 走看看