• 【BZOJ3721】PA2014 Final Bazarek 贪心


    【BZOJ3721】PA2014 Final Bazarek

    Description

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

    Input

    第一行一个整数n(1<=n<=1000000),表示商品数量。
    接下来一行有n个整数,表示每件商品的价格,范围在[1,10^9]。
    接下来一行有一个整数m(1<=m<=1000000),表示询问数量。
    接下来m行,每行一个整数k[i](1<=k[i]<=n)。

    Output

    对于每个询问,输出一行表示保证奇数的情况下最大的总价。若无法满足要求,输出-1。

    Sample Input

    4
    4 2 1 3
    3
    2
    3
    4

    Sample Output

    7
    9
    -1

    题解:考虑如果只有一次询问该怎么做。显然我们贪心的取最大的k个物品,若总价是奇数则直接出解,若为偶数,则要么将k个物品中最小的奇数换成剩下的物品中最大的偶数,要么将k个物品中最小的偶数换成剩下物品中最大的奇数。既然是多组询问,直接维护个前缀(后缀)奇数(偶数)最大(最小)值就行了。

    一开始zz了,离线用multiset求的最大最小值,结果被卡了~

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    int n,m;
    ll sum,ans[1000010],sm[2][1000010],sn[2][1000010];
    int v[1000010];
    int rd()
    {
    	int ret=0;	char gc=getchar();
    	while(gc<'0'||gc>'9')	gc=getchar();
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret;
    }
    bool cmp(int a,int b)
    {
    	return a>b;
    }
    int main()
    {
    	n=rd();
    	int i,k;
    	for(i=1;i<=n;i++)	v[i]=rd();
    	sort(v+1,v+n+1,cmp);
    	sm[0][n+1]=sm[1][n+1]=-1ll<<60,sn[0][0]=sn[1][0]=1ll<<60;
    	for(i=1;i<=n;i++)	sn[v[i]&1][i]=v[i],sn[(v[i]&1)^1][i]=sn[(v[i]&1)^1][i-1];
    	for(i=n;i>=1;i--)	sm[v[i]&1][i]=v[i],sm[(v[i]&1)^1][i]=sm[(v[i]&1)^1][i+1];
    	for(i=1;i<=n;i++)
    	{
    		sum+=v[i];
    		if(sum&1)	ans[i]=sum;
    		else
    		{
    			ans[i]=-1;
    			ans[i]=max(ans[i],sum-sn[0][i]+sm[1][i+1]);
    			ans[i]=max(ans[i],sum-sn[1][i]+sm[0][i+1]);
    		}
    	}
    	m=rd();
    	for(i=1;i<=m;i++)	k=rd(),printf("%lld
    ",ans[k]);
    	return 0;
    }

     

  • 相关阅读:
    python 基础第二篇
    python 基础第五篇
    python 基础第四篇
    购物小编程(完整编码)
    计算机 python概论
    str 相关操作
    python 基础第三篇
    Nginx 配置多站点vhost
    h5页面宽度设置7.5rem
    js 倒计时,转义
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7236430.html
Copyright © 2020-2023  润新知