zoukankan      html  css  js  c++  java
  • CF545C Woodcutters(贪心)题解

    贪心算法两句话

    第一句话:

    能往左倒就往左倒。

    如同数学中“我们不妨设”一样,相信很好理解。这里只对第二句话稍作解释:

    不能往左倒的尽量往右倒

    这样为什么是对的呢?

    我们可以分类讨论一下:

    • 假设当前已经处理到第(i)个,且它不能往左倒,(h_i)表示树高,(x_i)表示位置。

    • (x_{i + 1} - x_i > h_i),也就是说i可以往右倒,那么它有两种选择:

      1. 往右倒。如果倒完以后(i+1)还能向左倒,那么显然最优;如果倒完之后(i+1)不能往左倒了,

        那么在处理(i+1)时会考虑它能否往右,但我们发现([i-i + 1])这段区间内的贡献已达到了最大值(因为就算让(i + 1)往左倒这段区间对答案贡献也为(1)),因此不会使答案变差。

      2. 不往右倒。假如(i + 1)既能往左倒又能往右倒,那么如果(i)不往右倒就会影响答案,所以不能选。

    • (x_{i + 1} - x_i leq h_i),也就是说不能往右倒,这时它根本没得选。

    综上,我们证明了该贪心算法的正确性,希望这对你有所帮助。

    贴一波代码

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 1e5 + 10;
    int n,ans;
    struct Tree{
        int h,x;
    }t[maxn];
    
    int main(){
        scanf("%d", &n);
        for(int i = 1; i <= n; ++ i) scanf("%d%d", &t[i].x, &t[i].h);
        ans = 2;
        for(int i = 2; i < n; ++ i){
            if(t[i].x - t[i - 1].x > t[i].h) ans ++;
            else if(t[i + 1].x - t[i].x > t[i].h) ans ++, t[i].x += t[i].h;
        } printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    OpenCV 图像旋转
    单链表插入与删除数据
    opencv 数据训练
    C++ 小波变换
    二十七、miniscrapy,scrapy源码初解
    二十六、Scrapy自定义命令
    二十五、scrapy中的去重规则及自定义
    二十四、在scrapy中如何获取cookies
    十六、 IO多路复用,异步非阻塞
    五、IO模型简介
  • 原文地址:https://www.cnblogs.com/whenc/p/13854333.html
Copyright © 2011-2022 走看看