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;
}