有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大的数为X,将X替换成不在前K大的和X奇偶性不一样的最大的数,这样一定是最优的。

仔细思考了后发现这个命题不够完善 例如下面这个数据:

5

2 99 101 102 133

1000

1

2

3

唔 K=3时用上面那个算法做出来的是133+102+2 但最优的是133+101+99

于是完善了上面的算法:设在前K大的数中与X奇偶性相同的最小的数为Y(如果存在的话),那么把Y当成X替换成不在前K大中的奇偶性与Y不同的最大的那个数 这样算出的数和上面算法一算出的数取个最大值就是答案了

然后YY了个证明:设Bi表示i个数不在前k大数中的K个数的和的最大值,则Bi>=B(i+1),即i+1个数不在前K大里的答案绝对不优于i个数不在前K大里的答案

因此优先考虑0个数不在前K大里 即就是前K大的和 如果不为奇数,那么考虑只有1个数不在前K大里,显然通过以上方法一定能将和调整为奇数,或者题目无解。

接下来考虑为何用以上算法是调整一个数时的最大值:显然由于此时前K大的和为偶数,因此调整一个数要么把奇数调整成一个偶数,要么把偶数调整成一个奇数,那显然就是将最小的偶数调整成最大的奇数 或者最小的奇数调整成最大的偶数就可以了

//bzoj2464

#include <stdio.h>

#include <string.h>

#include <algorithm>

#include <iostream>

#define maxn 1000009

using namespace std;

int a[maxn],foredif[maxn],same[maxn],badif[maxn];

long long sum[maxn];

int cmp(int x, int y){return x>y;}

long long mmax(long long x,long long y)

{

return x>y?x:y;

}

int main()

{

long long n,k,lasto=-1,laste=-1,m;

scanf("%lld",&n);

for(int i=1;i<=n;i++)scanf("%lld",&a[i]);

sort(a+1,a+1+n,cmp);

for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];

for(int i=1;i<=n;i++)

{

if((a[i]&1)==1)//odd

{

foredif[i]=laste;

lasto=i;

}

else

{

foredif[i]=lasto;

laste=i;

}

}

lasto=laste=-1;

for(int i=n;i>=1;i--)

{

if((a[i]&1)==1)//odd

{

same[i]=lasto;

badif[i]=laste;

lasto=i;

}

else

{

same[i]=laste;

badif[i]=lasto;

laste=i;

}

}

scanf("%lld",&m);

for(int i=1;i<=m;i++)

{

scanf("%lld",&k);

long long s=sum[k];

if((s&1)==1){printf("%lld\n",s);continue;}

if(badif[k]==-1)

{

if(same[k]==-1||foredif[k]==-1)s=-1;else

s=(long long)s+(long long)a[same[k]]-(long long)a[foredif[k]];

}

else

{

if(same[k]==-1||foredif[k]==-1)s=s-(long long)a[k]+(long long)a[badif[k]];

else

{

s=mmax((long long)s+(long long)a[same[k]]-(long long)a[foredif[k]],(long long)s-(long long)a[k]+(long long)a[badif[k]]);

}

}

printf("%lld\n",s);

}

return 0;

}

BZOJ 3721: PA2014 Final Bazarek【乱搞】的更多相关文章

  1. BZOJ 3721: PA2014 Final Bazarek

    3721: PA2014 Final Bazarek Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 645  Solved: 261[Submit][ ...

  2. bzoj 3721: PA2014 Final Bazarek 贪心

    如果没有限制,直接取前 $k$ 大即可. 有限制,则只有几种可能:奇换偶,偶换奇. 维护奇数偶数的前缀最小值和后缀最大值即可. code: #include <bits/stdc++.h> ...

  3. 【BZOJ3721】PA2014 Final Bazarek 贪心

    [BZOJ3721]PA2014 Final Bazarek Description 有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价. Input 第一行一个整数n(1<=n ...

  4. bzoj 3722: PA2014 Final Budowa

    3722: PA2014 Final Budowa Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 303  Solved: 108[Submit][St ...

  5. BZOJ 3727 PA2014 Final Zadanie 树形DP

    题目大意:给定一棵树,令一个点到全部点的距离与点权的乘积之和为b[i].求每一个点的权值a[i] 首先假设给定a[i]我们能够非常轻松的求出b[i] 可是反过来怎么搞?高斯消元?30W? 考虑已知a[ ...

  6. bzoj3721 [PA2014 Final] Bazarek

    Description 有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价. Input 第一行一个整数n(1<=n<=1000000),表示商品数量.接下来一行有n个整数 ...

  7. 【BZOJ】2456 mode(乱搞)

    Description 给你一个n个数的数列,其中某个数出现了超过n div 2次即众数,请你找出那个数. Input 第1行一个正整数n.第2行n个正整数用空格隔开. Output 一行一个正整数表 ...

  8. bzoj 4900 [CTSC2017]密钥 模拟+乱搞

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4900 #include<cstring> #include<cmath&g ...

  9. 【贪心】bzoj3721 PA2014 Final Bazarek

    考虑不限制奇偶的情况,那就是直接排序取前k个的和. 加上奇偶限制:若排序后的前k个的和是偶数,则“显然地”:将其中的最小的奇数替换成未被选择的数中最大的偶数 或者 将其中的最小的偶数替换成未被选择的数 ...

随机推荐

  1. Unity3d的Sprite Packer用法介绍

    我们用来做sprite 的图片,通常会留有很多空白的地方,我们在画完了sprite之后,这些地方很可能就没有什么作用了.如果想避免这些资源上的浪费,我们可以把各个sprite做成图集,把图片上的空间尽 ...

  2. DedeCMS全版本通杀SQL注入漏洞利用代码及工具

    dedecms即织梦(PHP开源网站内容管理系统).织梦内容管理系统(DedeCms) 以简单.实用.开源而闻名,是国内最知名的PHP开源网站管理系统,也是使用用户最多的PHP类CMS系统,近日,网友 ...

  3. logging模块进阶

    python利用logging模块来记录日志主要涉及四个类 logger提供了应用程序可以直接使用的接口 handler将logger创建的日志提供的输出发送到指定目的地. filter起到过滤作用, ...

  4. 【程小白】Java基本特性

    一.StringBuffer.StringBuilder的区别 StringBuffer是线程安全的,StringBuilder是线程不安全的.所以以后在单线程中,如果涉及大量字符串操作,还是用Str ...

  5. java 之 插入排序

    思想:将一个数组分成两组,左边那组始终有序,每次取右边那组插入到左边适当的位置,保证左边有序,当右边没有需要插入的数据的时候,整个数组是有序的.插入排序是稳定排序. 注:此图引用自https://ww ...

  6. jdbc获取数据具体过程

    下面是个最简单的使用jdbc取得数据的应用.在例子之后我将分成4步,分别是①取得连接,②创建PreparedStatement,③设置参数,④执行查询,来分步分析这个过程.除了设置参数那一步之外,其他 ...

  7. 如何用sql server数据库恢复.bak数据库备份

    @hcy(黄灿奕) 之前有两次都恢复不了,折腾了很长时间,这一次碰到这样的问题,居然又忘了,又捣鼓了很长时间,现在记下来 1.右击SQL Server 2008实例下的“数据库”文件夹.就是与安全性. ...

  8. FPGA编程技巧系列之按键边沿检测

    抖动的产生: 通常的按键所用开关为机械弹性开关,当机械触点断开.闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开.因而在闭合及断开的瞬间均伴随有一连串的 ...

  9. laravel扩展包服务提供者的注册的两种方式

    一. 包自动发现 在 Laravel 应用的配置文件 config/app.php 中,providers 配置项定义了一个会被 Laravel 加载的服务提供者列表.当安装完新的扩展包后,在老版本中 ...

  10. easyui前端框架01

    一. 三大前端框架的特点 1.easyui=jquery+html4 优点:快速开发.功能齐全 .免费 缺点:不好看.不支持相应式开发 2.bootstrap=jquery+html5 优点: 功能强 ...