zoukankan      html  css  js  c++  java
  • Codeforces Round #466 (Div. 2) E. Cashback

    E. Cashback
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Since you are the best Wraith King, Nizhniy Magazin «Mir» at the centre of Vinnytsia is offering you a discount.

    You are given an array a of length n and an integer c.

    The value of some array b of length k is the sum of its elements except for the  smallest. For example, the value of the array [3, 1, 6, 5, 2] with c = 2 is 3 + 6 + 5 = 14.

    Among all possible partitions of a into contiguous subarrays output the smallest possible sum of the values of these subarrays.

    Input

    The first line contains integers n and c (1 ≤ n, c ≤ 100 000).

    The second line contains n integers ai (1 ≤ ai ≤ 109) — elements of a.

    Output

    Output a single integer  — the smallest possible sum of values of these subarrays of some partition of a.

    Examples
    input
    Copy
    3 5
    1 2 3
    output
    6
    input
    Copy
    12 10
    1 1 10 10 10 10 10 10 9 10 10 10
    output
    92
    input
    Copy
    7 2
    2 3 6 4 5 7 1
    output
    17
    input
    Copy
    8 4
    1 3 4 5 5 3 4 1
    output
    23
    Note

    In the first example any partition yields 6 as the sum.

    In the second example one of the optimal partitions is [1, 1], [10, 10, 10, 10, 10, 10, 9, 10, 10, 10] with the values 2 and 90 respectively.

    In the third example one of the optimal partitions is [2, 3], [6, 4, 5, 7], [1] with the values 3, 13 and 1 respectively.

    In the fourth example one of the optimal partitions is [1], [3, 4, 5, 5, 3, 4], [1] with the values 1, 21 and 1 respectively.

    思路:

            首先可以证明出最优方案中一定存在所有划分的块的元素量都不大于c。假设最优方案中存在大于c的块,规模为d,d % c = k, d / c = m, k不为0时,额外加入的这k个元素并不会使得当前块被砍掉的元素数量增多,也不会使被砍掉的元素增大,因此把这k个元素独立出来不会使结果变差;当k等于0时,即d是c的m倍时,合并m个规模为c的块不会使总共被砍掉的m个元素便大,相反可能变小。

            因此,我们考虑dp,dp[i]表示前i个元素可以被砍掉的最大和,则只需讨论目前最后一个(即第i个)元素是否被取到即可,被取到时,dp[i] = dp[i - c] + min(a[i - c + 1...i]);没被取到时,dp[i] = dp[i - 1]。其中求最小值可以用线段树维护。复杂度O(nlog(n))。

     1 #include <iostream>
     2 #include <fstream>
     3 #include <sstream>
     4 #include <cstdlib>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <string>
     8 #include <cstring>
     9 #include <algorithm>
    10 #include <queue>
    11 #include <stack>
    12 #include <vector>
    13 #include <set>
    14 #include <map>
    15 #include <list>
    16 #include <iomanip>
    17 #include <cctype>
    18 #include <cassert>
    19 #include <bitset>
    20 #include <ctime>
    21 
    22 using namespace std;
    23 
    24 #define pau system("pause")
    25 #define ll long long
    26 #define pii pair<int, int>
    27 #define pb push_back
    28 #define mp make_pair
    29 #define clr(a, x) memset(a, x, sizeof(a))
    30 
    31 const double pi = acos(-1.0);
    32 const int INF = 0x3f3f3f3f;
    33 const int MOD = 1e9 + 7;
    34 const double EPS = 1e-9;
    35 
    36 /*
    37 #include <ext/pb_ds/assoc_container.hpp>
    38 #include <ext/pb_ds/tree_policy.hpp>
    39 
    40 using namespace __gnu_pbds;
    41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
    42 */
    43 
    44 int mi[400015], n, c;
    45 ll sum;
    46 void pushup(int i) {
    47     mi[i] = min(mi[i << 1], mi[i << 1 | 1]);
    48 }
    49 void build(int i, int l, int r) {
    50     if (l == r) {
    51         scanf("%d", &mi[i]);
    52         sum += mi[i];
    53         return;
    54     }
    55     int mi = l + r >> 1;
    56     build(i << 1, l, mi);
    57     build(i << 1 | 1, mi + 1, r);
    58     pushup(i);
    59 }
    60 int query(int i, int l, int r, int x, int y) {
    61     if (x <= l && r <= y) {
    62         return mi[i];
    63     }
    64     int mi = l + r >> 1;
    65     int res1 = MOD, res2 = MOD;
    66     if (x <= mi) res1 = query(i << 1, l, mi, x, y);
    67     if (mi < y) res2 = query(i << 1 | 1, mi + 1, r, x, y);
    68     return min(res1, res2);
    69 }
    70 ll dp[100015];
    71 int main() {
    72     scanf("%d%d", &n, &c);
    73     build(1, 1, n);
    74     for (int i = c; i <= n; ++i) {
    75         int res = query(1, 1, n, i - c + 1, i);
    76         dp[i] = max(dp[i - 1], dp[i - c] + res);
    77     }
    78     printf("%lld", sum - dp[n]);
    79     return 0;
    80 }
  • 相关阅读:
    应用服务器安装
    datasnap的线程池
    压缩OLEVARIANT数据
    服务端日志记录
    提交主从表的多个已经修改的数据
    MySQL与PostgreSQL相比哪个更好?
    Vue入门常用指令详解
    Laravel模型事件的实现原理详解
    Git 遇到了 early EOF indexpack failed 问题
    Laravel 代码开发最佳实践
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/8468147.html
Copyright © 2011-2022 走看看