一、题目
二、解法
本题关键在于两个都喜欢的如何去选,既然难决策,我们就枚举,反正只有
我们把所有物品分为 类,都喜欢的, 喜欢的, 喜欢的,都不喜欢的。一开始尽量选都喜欢的,使之达到 个,从大到小枚举都喜欢的个数,都喜欢的减少 , 和 如果喜欢的都不够,去掉都不喜欢的,选一个 喜欢的,选一个 喜欢的。
如果只有一个不够或者都够,可以写一个函数来判断,这道题比较考察实现能力。
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int M = 200005;
int read()
{
int num=0,flag=1;
char c;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
while(c>='0'&&c<='9')num=(num<<3)+(num<<1)+(c^48),c=getchar();
return num*flag;
}
int n,m,k,t,A,B,la,lb,nr,mx,fk;
int l[4],a[M],vis[M],v[4][M];long long ans,s;
void solve(int x)
{
while(x--)
{
int mi=2e9,id=-1;
if(A<l[1] && v[1][A+1]<mi && lb>=k) mi=v[1][A+1],id=1;
if(B<l[2] && v[2][B+1]<mi && la>=k) mi=v[2][B+1],id=2;
if(nr<l[0] && v[0][nr+1]<mi && la>=k && lb>=k) mi=v[0][nr+1],id=3;
if(id==-1) {fk=1;return ;}
if(id==1) A++,la++;
if(id==2) B++,lb++;
if(id==3) nr++;
s+=mi;
}
}
signed main()
{
n=read();m=read();k=read();
for(int i=1;i<=n;i++) a[i]=read();
t=read();
for(int i=1;i<=t;i++) vis[read()]++;
t=read();
for(int i=1;i<=t;i++) vis[read()]+=2;
for(int i=1;i<=n;i++)
v[vis[i]][++l[vis[i]]]=a[i];
for(int i=0;i<4;i++)
sort(v[i]+1,v[i]+l[i]+1);
if(m<k || (l[3]<k && ((k-l[3])*2+l[3]>m || k-l[3]>l[1] || k-l[3]>l[2])))
{
puts("-1");
return 0;
}
mx=min(l[3],m);
for(int i=1;i<=mx;i++)
s+=v[3][i];
la=lb=mx;
while(A<k-l[3]) s+=v[1][++A],la++;
while(B<k-l[3]) s+=v[2][++B],lb++;
solve(m-mx-A-B);ans=s;
for(int i=mx;i>=1;i--)
{
la--;lb--;
s-=v[3][i];
if(la<k && lb<k)
{
if(A<l[1] && B<l[2] && nr>0)
s-=v[0][nr--],s+=v[1][++A],s+=v[2][++B],la++,lb++;//
else break;
}
else solve(1);
if(fk || la<k || lb<k) break;
ans=min(ans,s);
}
printf("%lld\n",ans);
}