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

Boboniu Chats with Du

题意

给你天数n,禁言时间d,上界m,再给你n个笑话,每个笑话有个搞笑值a,当a大于m时候,会被禁言,每天可以讲一个笑话,问怎么样可以使得搞笑值最大。

思路

根据有没有大于m,把笑话分为俩类,然后分别从大到小排序,给不会禁言的那组求个前缀。然后贪心的思路,考虑获得尽可能多的收益,选择前缀的长度(也就是天数),然后把剩下的天数全部用去会被沉默的天数。
考虑下特殊情况,就应为没想到wa24了,那就是全部选择会被沉默的天数,最后max一下就可以了。
如果没有大于m等,把所有的a加起来输出就可以了.
语文不好,qwq,再看下代码理解理解

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define IO ios::sync_with_stdio(false);
#define ll long long
#define pb push_back
using namespace std;
const int N=2e6+10;
const ll mod=1e9+7;
ll n,d,m;
ll a[N];
vector<ll>tmp;
vector<ll>tmpp;
bool cmp(ll a,ll b)
{
    return a>b;
}
void sovle()
{
    cin>>n>>d>>m;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
        if(a[i]<=m)
            tmp.pb(a[i]);
        else
        {
            tmpp.pb(a[i]);
        }
    }
    ll ans=0;
    if(tmpp.size()<1)
    {
        for(int i=0; i<n; i++)
            ans+=tmp[i];
        cout<<ans<<endl;
        return;
    }
    sort(tmpp.begin(),tmpp.end(),cmp);
    int l=0;
    int day=n;
    while(day>0)
    {
        ans+=tmpp[l];
        day-=(d+1);
        l++;
        if(l>=tmpp.size())
            break;
    }
    sort(tmp.begin(),tmp.end(),cmp);
    for(int i=1; i<tmp.size(); i++)
    {
        tmp[i]+=tmp[i-1];
    }
    for(int i=0; i<tmp.size(); i++)
    {
        ll sum=tmp[i];
        ll day=n-(i+1);
        ll l=0;
        while(day>0)
        {
            sum+=tmpp[l];
            day-=(d+1);
            l++;
            if(l>=tmpp.size())
                break;
        }
        ans=max(sum,ans);
    }
    cout<<ans<<endl;
}
int main()
{
//    int t;
//    cin>>t;
//    while(t--)
//    {
    sovle();
//    }
    return 0;
}
原文地址:https://www.cnblogs.com/Aracne/p/13495094.html