zoukankan      html  css  js  c++  java
  • BZOJ 3721: PA2014 Final Bazarek

    排序后,如果前k个是奇数,那么直接输出

    如果不是,我们考虑两种方式来变成奇数

    第一种,$去掉第k个数,然后在[k + 1, n] 中找一个与第k个数奇偶性不同的数替换上去$

    第二种,$选择第k + 1个数,然后在[1, k] 中选择一个与第k + 1个数奇偶性不同的数减去$

    注意要特判$n == k 的情况$

    考虑为什么这样可以,因为我们要想改变奇偶性,肯定要选择一个奇偶性不同的来换掉其中一个数

    那么就有上面两种方式

    那么会不会有可能存在换掉两个数或者更多的数使得答案更优呢 ,答案是不会

    因为如果假设这样正确的话,那么必定存在奇数对数,他们的奇偶性不同,也就是说至少存在一对数,奇偶性不同

    那么显然,我们只替换掉其中一对代价最小的,其他都不变,答案会更优

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 1000010
     6 int n, q;
     7 ll a[N], sum[N], pre[N], suf[N]; 
     8 
     9 bool cmp (int a, int b) { return a > b; }
    10 int main()
    11 {
    12     while (scanf("%d", &n) != EOF)
    13     {
    14         for (int i = 1; i <= n; ++i)
    15             scanf("%lld", a + i);
    16         sort(a + 1, a + 1 + n, cmp);
    17         for (int i = 1; i <= n; ++i) sum[i] = sum[i - 1] + a[i];
    18         ll odd = -1, even = -1;
    19         for (int i = 1; i <= n; ++i)
    20         {
    21             if (a[i] & 1)
    22             {
    23                 pre[i] = even;
    24                 odd = a[i];
    25             }
    26             else
    27             {
    28                 pre[i] = odd;
    29                 even = a[i];
    30             }
    31         }
    32         odd = even = -1;
    33         for (int i = n; i >= 1; --i)
    34         {
    35             if (a[i] & 1)
    36             {
    37                 suf[i] = even;
    38                 odd = a[i];
    39             }
    40             else
    41             {
    42                 suf[i] = odd;
    43                 even = a[i];
    44             }
    45         }
    46         scanf("%d", &q);
    47         for (int qq = 1, k; qq <= q; ++qq)
    48         {
    49             scanf("%d", &k);
    50             if (sum[k] & 1) printf("%lld
    ", sum[k]);
    51             else if (k == n) puts("-1");
    52             else
    53             {
    54                 ll tmp = -1;
    55                 if (suf[k] != -1) tmp = sum[k - 1] + suf[k]; 
    56                 if (pre[k + 1] != -1) tmp = max(tmp, a[k + 1] + sum[k] - pre[k + 1]);
    57                 printf("%lld
    ", tmp);
    58             }
    59         }
    60     }
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    jqueryautocomplete
    了解CSS的查找匹配原理 让CSS更简洁、高效
    html5网页编码
    刚开始学习 mvc碰到的郁闷问题
    datatable 批量插入方法 求解?
    28个经过重新设计的著名博客案例(1120)
    递归调用中的return
    C++新建一个模板
    C++ 中用 sizeof 判断数组长度
    为什么MySQL选择REPEATABLE READ作为默认隔离级别?
  • 原文地址:https://www.cnblogs.com/Dup4/p/10011257.html
Copyright © 2011-2022 走看看