Codeforces Round #664 (Div. 2) D. Boboniu Chats with Du

D. Boboniu Chats with Du

原题链接:

https://codeforces.ml/contest/1395/problem/D

题目大意:

在qq聊天中Du有$n$句话,每句话有不同的数值,一天只能说一句话,如果高于$m$的话就会在之后被禁言$d$天。要求出Du可以得到的最大值。

解题思路:

将$n$句话分成两部分,一部分是小于m的,另一部分是大于m的。首先将这两部分分别排序(从大到小),然后计算前缀和。接着可以枚举说的话小于m的个数i,如果$(n-  i )%(d + 1)$则可以取$(n-  i )/(d + 1)$,否则可以取$(n-  i )/(d + 1)+1$个。然后求出最大值即可。

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<ll,ll> pi;
 5 typedef complex <double> cp;
 6 #define debug(a) cout<<#a<<":"<<a<<endl;
 7 #define fr freopen("in.txt","r",stdin);
 8 #define Fill(x,a) memset(x,a,sizeof(x))
 9 #define cpy(a,b) memcpy(a,b,sizeof(a))
10 const double PI = acos(-1);
11 const ll INF=0x3f3f3f3f;
12 const ll N=1e6+7;
13 const ll mod=1e9+7;
14 ll maxn,minn;
15 ll T,n,m,q,d;
16 ll a[N];
17 ll b[N];
18 ll arr[N];
19 ll aa,bb;
20 ll dpa[N];
21 ll dpb[N];
22 
23 int main(){
24     cin>>n>>d>>m;
25     aa=bb=0;
26     for(ll i=1;i<=n;i++){
27         scanf("%lld",arr+i);
28         if(arr[i]>m){
29             b[++bb]=arr[i];
30         }
31         else{
32             a[++aa]=arr[i];
33         }
34     }
35     sort(a+1,a+aa+1);
36     sort(b+1,b+bb+1);
37     reverse(a+1,a+aa+1);
38     reverse(b+1,b+bb+1);
39     maxn=0;
40     Fill(dpa,0);
41     Fill(dpb,0);
42     for(ll i=1;i<=n;i++){
43         dpa[i]=dpa[i-1]+a[i];
44     }
45     for(ll i=1;i<=n;i++){
46         dpb[i]=dpb[i-1]+b[i];
47     }
48     for(ll i=0;i<=aa;i++){ 
49         int j;
50         if((n-i)%(d+1)==0){
51             j=(n-i)/(d+1);
52         }
53         else{
54             j=(n-i)/(d+1)+1;
55         }
56         maxn=max(maxn,dpa[i]+dpb[j]);
57     }
58     cout<<maxn<<endl;
59     
60     return 0;
61 }
62 
63  

原文地址:https://www.cnblogs.com/meanttobe/p/13514753.html