原题地址:http://codeforces.com/problemset/problem/545/C
题意解析
给n棵树的在一维数轴上的坐标,以及它们的高度。现在要你砍倒这些树,砍倒的树不能重合、当然也不能覆盖另外的树原来的位置,现在求最大可以看到的树的数目
解题思路
网上有很多人说这是DP,然而我怎么看都不需要用到DP。首先题中数据是按照坐标从小到大给出的,那我们直接从左到右每棵树依次看,那么显然可以有以下几点
- 最左边那棵树一定可以向左倒,最右边那棵树一定可以向右倒
- 每棵树,能向左倒就向左倒。(向左倒了后就不会影响下一棵)
- 每棵树,能倒就倒(每棵树向哪个方向倒,或者倒不倒,只受影旁边两棵树的影响,那么这棵树倒不倒只会影响到右边一棵树,绝不会传递给后一棵的决策)
那么很显然,这是贪心……按照这个思路,我们甚至可以边读入数据边处理,具体见下面的代码:
AC代码
//CodeForces-545C Woodcutters
//AC 2016-04-14 15:02:50
//greedy tricky
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <list>
#include <sstream>
#include <stack>
using namespace std;
#define cls(x) memset(x,0,sizeof x)
#define inf(x) memset(x,0x3f,sizeof x)
#define neg(x) memset(x,-1,sizeof x)
#define ninf(x) memset(x,0xc0,sizeof x)
#define st0(x) memset(x,false,sizeof x)
#define st1(x) memset(x,true,sizeof x)
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define abs(x) (x>0?x:-x)
#define max(x,y) (x>y?x:y)
#define min(x,y) (x<y?x:y)
#define bug cout<<"here"<<endl;
//#define debug
int main()
{
#ifdef debug
freopen("E:\Documents\code\input.txt","r",stdin);
freopen("E:\Documents\code\output.txt","w",stdout);
#endif
long long utmost=-INF,preh=0,cur=0,curh=0;
long long ans=0;
int n;
while(scanf("%d",&n)!=EOF)
{
bool left=1;
utmost=-INF;
ans=0;
while(n--)
{
scanf("%I64d %I64d",&cur,&curh);
if(!left)//if the previous tree didn't fall down leftwards, then check if it can fall down rightwards now
{
if(utmost+preh<cur)//fall rightwards
{
++ans;
utmost+=preh;
}
}
//check if this tree and fall leftwards
left=0;
if(cur-curh>utmost)
{
++ans;
left=1;
}
utmost=cur;
preh=curh;
}
if(!left)
++ans;
printf("%lld
",ans);
}
return 0;
}