CF545C Woodcutters(贪心)题解
Posted whenc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF545C Woodcutters(贪心)题解相关的知识,希望对你有一定的参考价值。
贪心算法两句话
第一句话:
能往左倒就往左倒。
如同数学中“我们不妨设”一样,相信很好理解。这里只对第二句话稍作解释:
不能往左倒的尽量往右倒
这样为什么是对的呢?
我们可以分类讨论一下:
-
假设当前已经处理到第(i)个,且它不能往左倒,(h_i)表示树高,(x_i)表示位置。
-
若(x_{i + 1} - x_i > h_i),也就是说i可以往右倒,那么它有两种选择:
-
往右倒。如果倒完以后(i+1)还能向左倒,那么显然最优;如果倒完之后(i+1)不能往左倒了,
那么在处理(i+1)时会考虑它能否往右,但我们发现([i-i + 1])这段区间内的贡献已达到了最大值(因为就算让(i + 1)往左倒这段区间对答案贡献也为(1)),因此不会使答案变差。
-
不往右倒。假如(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;
}
以上是关于CF545C Woodcutters(贪心)题解的主要内容,如果未能解决你的问题,请参考以下文章
「日常训练」Woodcutters(Codeforces Round 303 Div.2 C)
CF3D Least Cost Bracket Sequence 题解——贪心