首页 > 代码库 > BZOJ 3727 PA2014 Final Zadanie 贪心
BZOJ 3727 PA2014 Final Zadanie 贪心
题目大意:给定n个数,多次询问选择k个数使和为奇数的最大和
首先将所有数排序
对于每个询问,如果最大的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 3727 PA2014 Final Zadanie 贪心
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。