Description
有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价。
Input
第一行一个整数n(1<=n<=1000000),表示商品数量。
接下来一行有n个整数,表示每件商品的价格,范围在[1,10^9]。
接下来一行有一个整数m(1<=m<=1000000),表示询问数量。
接下来m行,每行一个整数ki。
Output
对于每个询问,输出一行表示保证奇数的情况下最大的总价。若无法满足要求,输出-1。
Sample Input
4
4 2 1 3
3
2
3
4
Sample Output
7
9
-1
HINT
Source
鸣谢Jcvb
省队集训时候Delayyy讲过的题.
贪心.
把所有数从大到小排序记录前缀和,然后分奇偶性,然后对奇数偶数分别记录前缀最小后缀最大来回答询问.
前k个前缀和为奇,则直接输出就行了
否则考虑以奇换偶或者以偶换奇.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXINT 0x7fffffff
#define MAXN 1000100
#define LL long long
using namespace std;
int n,m,q;
int k[MAXN];
LL pre[MAXN],min1[MAXN],min2[MAXN],max1[MAXN],max2[MAXN],ans;
void in(int &x)
{
char ch=getchar();x=0;int flag=1;
while (!(ch>='0'&&ch<='9')) flag=ch=='-'?-1:flag,ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();x*=flag;
}
bool cmp(LL a,LL b)
{
return a>b;
}
int main()
{
in(n);
for (int i=1;i<=n;i++) in(k[i]);
sort(k+1,k+n+1,cmp);
for (int i=1;i<=n;i++) pre[i]=pre[i-1]+k[i];
min1[0]=MAXINT;min2[0]=MAXINT;
for (int i=1;i<=n;i++)
{
min1[i]=min1[i-1];min2[i]=min2[i-1];
if (k[i]&1) min1[i]=min(min1[i],(LL)k[i]);
else min2[i]=min(min2[i],(LL)k[i]);
}
for (int i=n;i;i--)
{
max1[i]=max1[i+1];max2[i]=max2[i+1];
if (k[i]&1) max1[i]=max(max1[i],(LL)k[i]);
else max2[i]=max(max2[i],(LL)k[i]);
}
in(m);
for (int i=1;i<=m;i++)
{
in(q);
if (pre[q]&1) printf("%lld\n",pre[q]);
else
{
ans=-1;
if (min1[q]!=MAXINT&&max2[q+1]) ans=max(ans,pre[q]-min1[q]+max2[q+1]);
if (min2[q]!=MAXINT&&max1[q+1]) ans=max(ans,pre[q]-min2[q]+max1[q+1]);
printf("%lld\n",ans);
}
}
}