zoukankan      html  css  js  c++  java
  • Day3-Q-修补木桶 HihoCoder1362

    一只木桶能盛多少水,并不取决于桶壁上最高的那块木板,而恰恰取决于桶壁上最短的那块。

    已知一个木桶的桶壁由N块木板组成,第i块木板的长度为Ai。

    现在小Hi有一个快捷修补工具,每次可以使用修补工具将连续的不超过L块木板提高至任意高度。

    已知修补工具一共可以使用M次(M*L<N),如何修补才能使最短的那块木板最高呢?

    注意: 木板是环形排列的,第N-1块、第N块和第1块也被视为连续的。

    Input

    第1行:3个正整数,N, M, L。分别表示木板数量,修补工具使用次数,修补工具每次可以同时修补的木板数。 1≤N≤1,000,1≤L≤20,M*L<N

    第2行:N个正整数,依次表示每一块木板的高度Ai,1≤Ai≤100,000,000

    Output

    第1行:1个整数。表示使用修补工具后,最短木块的所能达到的最高高度

    Sample Input

    8 2 3
    8 1 9 2 3 4 7 5

    Sample Output

    7

    Hint

    第一个修补工具覆盖[2 3 4]

    第二个修补工具覆盖[5 8 1]

     思路:可贪心验证+答案单调性,二分答案,验证时枚举起点即可,代码如下:

    const int maxm = 100010;
    const int INF = 0x7fffffff;
    
    int buf[maxm], N, M, L;
    
    bool check(int d) {
        int start = 0, sum;
        while(start < N) {
            sum = 0;
            for(int i = start; i < start + N;) {
                if(buf[i % N] < d) {
                    i += L;
                    sum++;
                } else
                    i++;
            }
            if(sum <= M)
                return true;
            start++;
        }
        return false;
    }
    
    int main() {
        scanf("%d%d%d", &N, &M, &L);
        int l = INF, r = -INF, mid;
        for(int i = 0; i < N; ++i) {
            scanf("%d",&buf[i]);
            l = min(l, buf[i]), r = max(r, buf[i]);
        }
        while(l <= r) {
            mid = (l + r) >> 1;
            if(check(mid))
                l = mid + 1;
            else
                r = mid - 1;
        }
        printf("%d
    ", r);
        return 0;
    }
    View Code
  • 相关阅读:
    Solution: Win 10 和 Ubuntu 16.04 LTS双系统, Win 10 不能从grub启动
    在Ubuntu上如何往fcitx里添加输入法
    LaTeX 笔记---Q&A
    Hong Kong Regional Online Preliminary 2016 C. Classrooms
    Codeforces 711E ZS and The Birthday Paradox
    poj 2342 anniversary party
    poj 1088 滑雪
    poj 2479 maximum sum
    poj 2481 cows
    poj 2352 stars
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/11250078.html
Copyright © 2011-2022 走看看