zoukankan      html  css  js  c++  java
  • WYT的刷子

    WYT的刷子

    题目描述

    WYT有一把巨大的刷子,刷子的宽度为M米,现在WYT要使用这把大刷子去粉刷有N列的栅栏(每列宽度都为1米;每列的高度单位也为米,由输入数据给出)。

    使用刷子的规则是:

    1. 与地面垂直,从栅栏的底部向上刷
    2. 每次刷的宽度为M米(当剩余栅栏宽度不够M米的话,刷子也可以使用,具体看样例2)
    3. 对于连续的M列栅栏,刷子从底向上,刷到的高度只能到这M列栅栏的最低高度。

    WYT请你回答两个问题:

    1. 最少有多少个单位面积不能刷到(单位面积为1平米)
    2. 在满足第一问的条件下,最少刷几次?

    输入格式

    共两行:

    第一行两个整数N和M。

    第二行共N个整数,表示N列栅栏的高度

    输出格式

    一行,两个整数,分别为最少剩余的单位面积数量和最少刷的次数。

    样例

    样例输入1

    5 3
    5 3 4 4 5
    

    样例输出1

    3
    2
    

    样例输入2

    10 3
    3 3 3 3 3 3 3 3 3 3
    

    样例输出2

    0
    4
    

    样例输入3

    7 4
    1 2 3 4 3 2 1
    

    样例输出3

    4
    4
    

    样例1的解释:

    image

    高度分别为 5 3 4 4 5 如上:

    黄色的方块表示共有3个单位面积没刷上

    绿色的框和红色的框表示一共刷了两次。

    数据范围与提示

    30%的数据:N<=10^3

    50%的数据:N<=10^5

    100%的数据:1<=N<=10^6, 1<=M<=10^6,N>=M, 每列栅栏的高度<=10^6.

    code

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e6 + 10, INF = 0x3f3f3f3f;
    
    struct Node {
        int id;
        long long high;
    } sol[maxn], solmin[maxn], solmax[maxn];
    
    long long height[maxn], f[maxn];
    long long ans = 0;
    int flag = 1, t = 0;
    int n, m;
    void get_min() {
        for (int i = 1; i <= n; i++) {
            while (flag <= t && sol[t].high >= height[i]) t--;
            t++;
            sol[t].id = i;
            sol[t].high = height[i];
            if (i >= m) {
                if (sol[flag].id <= i - m)
                    flag++;
                solmin[i].high = sol[flag].high;
                solmin[i].id = sol[flag].id;
            }
        }
        for (int i = 1; i < m; i++) {
            solmin[i].id = i;
            solmin[i].high = -INF;
        }
    }
    
    void get_max() {
        flag = 1, t = 0;
        for (int i = 1; i <= n; i++) {
            while (flag <= t && solmax[t].high <= solmin[i].high) t--;
            solmax[++t].id = i;
            solmax[t].high = solmin[i].high;
            if (i >= m) {
                if (solmax[flag].id <= i - m)
                    flag++;
                f[i - m + 1] = solmax[flag].high;
                ans += height[i - m + 1] - f[i - m + 1];
            }
        }
        long long maxh = -INF;
        for (int i = n; i > n - m + 1; i--) {
            maxh = max(maxh, solmin[i].high);
            f[i] = maxh;
            ans = ans + height[i] - f[i];
        }
    }
    
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; i++) cin >> height[i];
        get_min();
        get_max();
        int last = 1, num = 1;
        for (int i = 1; i <= n; i++) {
            if (i - last + 1 > m || f[last] != f[i]) {
                last = i;
                num++;
            }
        }
        cout << ans << endl << num << endl;
        return 0;
    }
    
  • 相关阅读:
    动态规划----背包问题
    动态规划----最长公共子序列
    贪心算法---codeforce680D Bear and Tower of Cubes
    贪心算法----Fence Repair(POJ 3253)
    线段树拓展----HDU 6315 Naive Operations
    Saruman`s Army(POJ 3069)
    字典序最小问题 Best Cow Line (POJ 3617)
    RMQ
    牛客2018年第二次acm暑期培训----H-Diff-prime Pairs
    牛客2018年第二次多校培训----A-run
  • 原文地址:https://www.cnblogs.com/hellohhy/p/13221282.html
Copyright © 2011-2022 走看看