codeforces799E Aquarium decoration

题目大意:

给定 n 个数,有2个人,每个人有几个喜欢的数,要从中选恰好 m 个数,使每个人都至少有k个喜欢的数被选到。求最小代价。

枚举选几个两个人都喜欢的数,然后贪心求答案就可以了。

代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 200010
#define ll long long
#define INF 2000000000
ll Ans=1e18,Res;
int i,j,k,n,Sum,m,x,y,l[4],a[N],b[4][N],p[4],M,f[N];
inline int Min(int x,int y){return x<y?x:y;}
inline ll Min(ll x,ll y){return x<y?x:y;}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=n;i++)scanf("%d",&a[i]);
    scanf("%d",&x);
    while(x--)scanf("%d",&y),f[y]=1;
    scanf("%d",&x);
    while(x--){
        scanf("%d",&y);
        if(f[y])f[y]=3;else f[y]=2;
    }
    for(i=1;i<=n;i++)
    if(f[i]==3)b[0][++l[0]]=a[i];else
    if(f[i]==1)b[1][++l[1]]=a[i];else
    if(f[i]==2)b[2][++l[2]]=a[i];else b[3][++l[3]]=a[i],f[i]=l[3];
    sort(b[0]+1,b[0]+l[0]+1);sort(b[1]+1,b[1]+l[1]+1);
    sort(b[2]+1,b[2]+l[2]+1);sort(b[3]+1,b[3]+l[3]+1);
    for(i=0;i<4;i++)b[i][l[i]+1]=INF,p[i]=1;
    for(i=0;i<=l[0]&&i<=m;i++){
        if(k-i>l[1]||k-i>l[2])continue;
        while(p[0]<=i){
            Res+=b[0][p[0]++];
            Sum++;
        }
        if(k-i+2==p[1]){
            Res-=b[1][--p[1]];
            Sum--;
        }
        while(k-i>=p[1]){
            Res+=b[1][p[1]++];
            Sum++;
        }
        if(k-i+2==p[2]){
            Res-=b[2][--p[2]];
            Sum--;
        }
        while(k-i>=p[2]){
            Res+=b[2][p[2]++];
            Sum++;
        }
        while(Sum<m){
            M=INF;
            for(j=0;j<4;j++)if(p[j]<=l[j])M=Min(M,b[j][p[j]]);
            if(M==INF)break;
            for(j=0;j<4;j++)
            if(b[j][p[j]]==M){
                Res+=b[j][p[j]++];
                break;
            }
            Sum++;
        }
        if(Sum==m)Ans=Min(Ans,Res);
    }
    if(Ans==1e18)puts("-1");else printf("%I64d\n",Ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值