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