题解:B4427 [CSP-X2025 山东] 能量水晶
UltimaRatio · · 题解
CSP-X 重现赛中打到的挺有趣的一题,可惜赛时挂分了。感觉 -X 出的比 -J 好。
题意就不说了,没看题意不建议直接看题解。
思路
要想让前
:::success[证明]
显然。
如果我们使第
:::
得到这个结论后考虑如何求出第
如何判断一个第
当前试的第
算法到这里已经很明确了,我们求出可以构造的
:::info[如何调整]
把同一个
:::
:::success[代码]{open}
#include<bits/stdc++.h>
#define int long long
#define double long double
#define fi first
#define se second
#define pii pair<int,int>
#define endl '\n'
using namespace std;
const int N=2e3+10;
int n;
int m,k;
int a[N];
int mx;
int ans;
signed main(){
// freopen("energy.in","r",stdin);
// freopen("energy.out","w",stdout);
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
mx=max(mx,a[i]);
}
for(int asd=1;asd<=mx;asd++){//枚举第 $ k $ 小
const int x=asd;
priority_queue<int>pq;//用于算答案
int cnt=0;
for(int i=1;i<=n;i++){
cnt+=a[i]/x;
if(a[i]%x){
pq.push(a[i]%x);
}
}
cnt-=m-k;
if(cnt<=0){//不合法直接continue
continue;
}
cnt=min(cnt,k);
int sum=cnt*x;
for(int i=1;i<=k-cnt;i++){
if(pq.empty()){//前k-1小凑不齐也不合法
sum=-1;
break;
}
sum+=pq.top();
pq.pop();
}
if(sum==-1){
continue;
}
ans=max(ans,sum);
}
if(k>=n){//特判
int sum=0;
for(int i=1;i<=n;i++){
sum+=a[i];
}
ans=max(ans,sum);
}
cout<<ans<<endl;
return 0;
}
:::