bzoj3721PA2014 Final Bazarek 贪心

27 篇文章 0 订阅

题意:有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价。

思路巧妙的贪心,由于判断一开始写错了导致没有1A。
每次直接选取最大的k个,然后如果是偶数的话就把k个中最小的偶数替换成后面最大的奇数或者把k个中最小的奇数换成后面最大的偶数,因为只有奇数才能改变奇偶性,所以正确性显然。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e6+5;
typedef long long ll;
const ll inf=1e15;
int n,m;

ll a[N],mx0[N],mx1[N],mn0[N],mn1[N];
ll sum[N],ans[N];
bool cmp(ll a,ll b)
{
    return a>b;
}
int main()
{
    scanf("%d",&n);
    fo(i,1,n)scanf("%lld",&a[i]);
    sort(a+1,a+1+n,cmp);

    fd(i,n,1)
    {
        mn0[i]=mn1[i]=inf;
        mx0[i]=mx0[i+1],mx1[i]=mx1[i+1];
        mx0[i]=max(mx0[i],a[i]%2==0?a[i]:0);
        mx1[i]=max(mx1[i],a[i]%2==1?a[i]:0);
    }
    mn0[0]=mn1[0]=inf;
    fo(i,1,n)
    {
        mn0[i]=mn0[i-1],mn1[i]=mn1[i-1];
        mn0[i]=min(mn0[i],a[i]%2==0?a[i]:inf);
        mn1[i]=min(mn1[i],a[i]%2==1?a[i]:inf);
        sum[i]=sum[i-1]+a[i]; 
    }
    scanf("%d",&m);
    fo(i,1,m)
    {
        int x;
        scanf("%d",&x);
        ll ans=-1;
        if (sum[x]%2==1)ans=max(ans,sum[x]);
        else
        {
            if (mn0[x]!=inf&&mx1[x+1])
            ans=max(ans,sum[x]-mn0[x]+mx1[x+1]);
            if (mn1[x]!=inf&&mx0[x+1]) 
            ans=max(ans,sum[x]-mn1[x]+mx0[x+1]);
        }
        printf("%lld\n",ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值