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 }
  • 相关阅读:
    非易失性Flash详解
    易失性存储器SRAM基础知识
    嵌入式STT-MRAM效应与流致反转
    访问SDRAM的低功耗优化设计方案
    SRAM的容量扩展
    SDRAM功耗来源
    如何使FRAM MCU速度更快所需功耗最低
    Nand Flash结构及错误机制
    提升SRAM性能的传统方法
    word在一个文档中使用多个页码,页眉
  • 原文地址:https://www.cnblogs.com/BIGTOM/p/8468147.html
Copyright © 2011-2022 走看看