题解:P12076 [OOI 2025] Cute Subsequences
简要题意
给定一个长度为
其中
思路
对于一个子序列,其价值不仅与选择了哪些元素有关,同时也与这些元素在子序列中所处的位置有关。由于位置随位置从
- 在
k 个子序列中,将最靠右(即下标最大的那个)的子序列保持不变,这个子序列的贡献为a_x + x (假设x = \max\{i_1, i_2, \dots, i_k\} )。 - 其他
k-1 个子序列,我们都将让使价值最大的元素放在序列的最前面,这样它们的位置都是1 ,贡献就是各自的a_{i} 加上1 。
因为
对于每个可能的
x (表示最靠右的选中元素位置),如何在x 前面(即区间[1, x-1] )选择k-1 个元素,使它们的和最大?
我们枚举
代码
#include<bits/stdc++.h>
#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)
using namespace std;
const int N=5000010;
int n,k;
int a[N],tot,ans;
priority_queue<int,vector<int>,greater<int> > q;
main(){
cin>>n>>k;
rep(i,1,n)cin>>a[i];
rep(i,1,k-1)q.push(a[i]),tot+=a[i];
ans=max(ans,k+a[k]+tot);
rep(i,k+1,n){
if(!q.empty()){
if(q.top()<a[i-1])tot-=q.top(),q.pop(),tot+=a[i-1],q.push(a[i-1]);
}
ans=max(ans,i+a[i]+tot);
}
cout<<ans;
return 0;
}