BZOJ 3721 PA2014 Final Bazarek 贪心
2014-11-25 16:55
309 查看
题目大意:给定n个数,多次询问选择k个数使和为奇数的最大和
首先将所有数排序
对于每个询问,如果最大的k个数之和是奇数,那么答案显然是这k个数的和
如果最大的k个数之和是偶数,那么我可以将后k个数中最小的偶数换成前n-k个数中最大的奇数,或者将后k个数中最小的奇数换成前n-k个数中最大的偶数
二者取最优即可 无法如此做则输出-1
首先将所有数排序
对于每个询问,如果最大的k个数之和是奇数,那么答案显然是这k个数的和
如果最大的k个数之和是偶数,那么我可以将后k个数中最小的偶数换成前n-k个数中最大的奇数,或者将后k个数中最小的奇数换成前n-k个数中最大的偶数
二者取最优即可 无法如此做则输出-1
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1001001 using namespace std; int n,m,k,a[M]; long long min_num[M][2],pre[M][2]; long long sum[M],ans; int main() { int i; cin>>n; for(i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); min_num[n+1][0]=min_num[n+1][1]=1e15; for(i=n;i;i--) { sum[i]=sum[i+1]+a[i]; min_num[i][a[i]&1]=a[i]; min_num[i][~a[i]&1]=min_num[i+1][~a[i]&1]; } pre[0][0]=pre[0][1]=-1e15; for(i=1;i<=n;i++) { pre[i][a[i]&1]=a[i]; pre[i][~a[i]&1]=pre[i-1][~a[i]&1]; } cin>>m; for(i=1;i<=m;i++) { scanf("%d",&k); if(sum[n-k+1]&1) { printf("%lld\n",sum[n-k+1]); continue; } ans=sum[n-k+1]; long long x=min_num[n-k+1][0]-pre[n-k][1]; long long y=min_num[n-k+1][1]-pre[n-k][0]; if(x>=1e14&&y>=1e14) { puts("-1"); continue; } ans-=min(x,y); printf("%lld\n",ans); } }
相关文章推荐
- BZOJ 3721 PA 2014 Final Bazarek 贪心
- 【 BZOJ 3721】 PA2014 Final Bazarek 贪心
- bzoj 3721: PA2014 Final Bazarek 单调栈+贪心
- BZOJ 3721 PA2014 Final Bazarek
- BZOJ 3721: PA2014 Final Bazarek
- BZOJ系列3721《PA2014 Final Bazarek》题解
- BZOJ 3721: PA2014 Final Bazarek【乱搞】
- 3721: PA2014 Final Bazarek|贪心
- bzoj 3721 PA2014 Final Bazarek
- 3721: PA2014 Final Bazarek (贪心)
- 【贪心】bzoj3721 PA2014 Final Bazarek
- bzoj 3725: PA2014 Final Matryca (贪心)
- 【BZOJ】3709: [PA2014]Bohater(贪心)
- bzoj 3709: [PA2014]Bohater 贪心
- 【贪心】bzoj3709 [PA2014]Bohater
- BZOJ3709 [PA2014]Bohater 【贪心】
- BZOJ 3709: [PA2014]Bohater 贪心
- 【BZOJ4619/3709】[Wf2016]Swap Space/[PA2014]Bohater 贪心
- bzoj 3709: [PA2014]Bohater【贪心】
- BZOJ 3709: [PA2014]Bohater 贪心