题目大意:给定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); } }
时间: 2024-10-13 13:38:30