AT4724 [ABC128D] equeue 题解
题目传送门
思路
这一题可以看成从左边取出 \(l\) 个宝石,从右边取出 \(r\) 个宝石,最后从手中取出 \(k-l-r\) 颗宝石。
但是从手中取出的 \(k-l-r\) 颗宝石不一定是手中最小的 \(k-l-r\)颗,因为题目说你最多可以进行 \(K\) 次(可能为 \(0\))的操作。
只有负数才会减少手中宝石的价值,因此,最小的 \(k-l-r\) 颗宝石只需要删除其中的负数即可。
因为本题的 \(n\) 数据范围很小,所以直接暴力枚举 \(l\) 和 \(r\),对于每一组合法的 \(l\) 和 \(r\) 算出答案,取一个最大值。
代码的时间复杂度为 \(O(n^3)\)。
代码如下
//#include<bits/stdc++.h>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f,MOD=1e9+7;
#define pu putchar
#define endl puts("")
//#define int __int128
//#define int long long
#define rep(i,l,r) for(int i=l;i<=r;++i)
#define per(i,r,l) for(int i=r;i>=l;--i)
#define me0(a); memset(a,0,sizeof a);
#define me3(a); memset(a,0x3f,sizeof a);
#define PII pair<int,int>
void read(int &n){char c,w=1;for(;48>c||c>57;c=getchar())
w=c==45?-1:1;for(n=0;47<c&&c<58;c=getchar())n=n*10+c-48;n*=w;
}void write(int x){if(x<0)pu(45),x=-x;char c[41],s=0;
for(;x;)c[s++]=x%10,x/=10;if(!s)pu(48);for(;s--;)pu(c[s]+48);
}void debug(int n){printf("\tdebug:\t"); write(n); pu('\t');}
const int MAXN=100+10;
int n,k;
int ans;
int a[MAXN],s[MAXN];
main(){
read(n); read(k);
rep(i,1,n){
read(a[i]);
}rep(l,0,n){
rep(r,0,n-l){
if(l+r<=k){
int pos,tot=0,sum=0;
rep(i,1,l){
s[++tot]=a[i];
}rep(i,n-r+1,n){
s[++tot]=a[i];
}sort(s+1,s+tot+1);
for(pos=1;pos<=k-l-r;++pos)
if(s[pos]>=0){
break;
}
rep(i,pos,tot){
sum+=s[i];
}ans=max(ans,sum);
}
}
}write(ans); endl;
}