CodeForces-545C Woodcutters 【贪心+机智】

原题地址: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\n",ans);
    }
    return 0;
}
posted @ 2016-04-20 23:39  DrCarl  阅读(275)  评论(0编辑  收藏  举报