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
  • 相关阅读:
    多态小结
    Lambda小结
    网络编程小结
    内部类与Lambda
    线程小结
    关于java的静态绑定与动态绑定小结
    多线程
    英语语法十二(可数名词不规则变化)
    英语语法入门十四(名词的作用)
    英语语法入门十三(不可数名词)
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/11250078.html
Copyright © 2011-2022 走看看