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);
    }
}
时间: 2024-10-13 13:38:30

BZOJ 3727 PA2014 Final Zadanie 贪心的相关文章

BZOJ 3727 PA2014 Final Zadanie 树形DP

题目大意:给定一棵树,令一个点到所有点的距离与点权的乘积之和为b[i],求每个点的权值a[i] 首先如果给定a[i]我们可以很轻松的求出b[i] 但是反过来怎么搞?高斯消元?30W? 考虑已知a[i]求b[i]的情况 令这棵树的根为1 点i到根节点的距离为dis[i] 以i为根的子树的a值之和为size[i] 那么有递推式 b[1]=Σa[i]*dis[i] b[x]=b[fa[x]]-2*size[x]+size[1] 将上式变形得: 2*size[x]=b[fa[x]]-b[x]+size[

【BZOJ 3727】 3727: PA2014 Final Zadanie (递推)

3727: PA2014 Final Zadanie Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 279  Solved: 121 Description 吉丽YY了一道神题,题面是这样的:"一棵n个点的树,每条边长度为1,第i个结点居住着a[i]个人.假设在i结点举行会议,所有人都从原住址沿着最短路径来到i结点,行走的总路程为b[i].输出所有b[i]."吉丽已经造好了数据,但熊孩子把输入文件中所有a[i]给删掉了.你能帮他恢复吗?

【BZOJ3721】PA2014 Final Bazarek 贪心

[BZOJ3721]PA2014 Final Bazarek Description 有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价. Input 第一行一个整数n(1<=n<=1000000),表示商品数量.接下来一行有n个整数,表示每件商品的价格,范围在[1,10^9].接下来一行有一个整数m(1<=m<=1000000),表示询问数量.接下来m行,每行一个整数k[i](1<=k[i]<=n). Output 对于每个询问,输出一行表示保证奇数的

【BZOJ-3721】Final Bazarek 贪心

3721: PA2014 Final Bazarek Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 610  Solved: 243[Submit][Status][Discuss] Description 有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价. Input 第一行一个整数n(1<=n<=1000000),表示商品数量.接下来一行有n个整数,表示每件商品的价格,范围在[1,10^9].接下来一行有一个整数m(1&l

BZOJ 3727 Final Zadanie

递推一下什么的就好了... #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 300050 #define maxe 600050 using namespace std; long long n,x,y,g[maxv],nume=1,tot1=0,tot2=0,dis[maxv],b[maxv],sum[maxv]; long lon

【贪心】bzoj 3709:[PA2014]Bohater

3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 653  Solved: 220[Submit][Status][Discuss] Description 在一款电脑游戏中,你需要打败n只怪物(从1到n编号).为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值.任何时候你的生命值都不能降到0(或0以下).请问是否存在一种打怪顺序

BZOJ 3721 PA 2014 Final Bazarek 贪心

题目大意:有n件商品,选出其中的k个,要求它们的总价为奇数,求最大可能的总价. 思路:一个O(n)的贪心,先排序,然后O(n)预处理每个节点之前出现的最大奇数和偶数,和每一个节点之后出现的最小的奇数或者偶数,之后每个询问O(1)判断一下.注意初值. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1000010 #d

【BZOJ】3709: [PA2014]Bohater(贪心)

http://www.lydsy.com/JudgeOnline/problem.php?id=3709 很水的题...但是由于脑洞小..漏想了一种情况.. 首先显然能补血的先杀.. 然后杀完后从补血越多的杀..(这点我之前考虑错了QAQ) 正确性显然........ #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream>

【贪心】bzoj3721 PA2014 Final Bazarek

考虑不限制奇偶的情况,那就是直接排序取前k个的和. 加上奇偶限制:若排序后的前k个的和是偶数,则“显然地”:将其中的最小的奇数替换成未被选择的数中最大的偶数 或者 将其中的最小的偶数替换成未被选择的数中最大的奇数 是最优的. 那么排序之后 就可以预处理出 某个位置左侧最小的奇数.左侧最小的偶数.右侧最大的奇数.右侧最大的偶数,然后就可以O(1)地回答每个询问了. 开long long 1 #include<cstdio> 2 #include<algorithm> 3 using