codeforces 545C Woodcutters

题目链接 http://codeforces.com/problemset/problem/545/C

题意:

一个在二维平面的伐木工想要砍尽可能的树。树有自己的坐标x[i]和高度h[i]。

如果一个树被砍下后,我们可以让它往左倒下,也可以往右倒下。

我们不移动倒下的树,树倒下后,

如果第i棵树往左倒就占据 [x[i]-h[i],x[i] ]的位置,如果往右倒,就占据[x[i],x[i]+h[i]]的位置。

如果这个区间上原本有一些其他树的占据点,那么它们就不能往这个方向倒。

一颗没有被砍的树i。占据x[i]这个点。求伐木工一次可以砍倒几颗树。

题目做法。

从左往右砍树。

如果它能往左倒,就往左砍倒它。如果能往右倒。就往右砍到它。否则不砍它。

一种贪心的思想,因为砍倒当前这棵树只对它右边的第一颗树影响。

而我们既然能砍倒它,就不用考虑影响到砍到它右边了,因为反正砍倒它+1,砍倒它后面的也+1。那样对于右边的右边的那颗树来说,无疑是这样砍是最优的。

代码如下:

#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long LL;
typedef long long ll; 
const int maxn = 1e6+6;
const int INF = 0x3f3f3f3f;
char str[maxn];
int a[maxn];
int dpx[maxn]; //dpx[i]记录砍到第i棵树的占据的最右边的端点 
int dpnum[maxn];//dpnum[i]记录砍到第i棵的最优砍法 
int h[maxn];
int x[maxn];
void show(int a[],int n){
	for(int i=0;i<n;i++){
		printf("%d ",a[i]);
	}printf("\n");
}
int main(){
//	freopen("C:\\Users\\lenovo\\Desktop\\data.in","r",stdin);
	int n;
	while(scanf("%d",&n)+1){
		
		for(int i=0;i<n;i++){
			scanf("%d%d",x+i,h+i);
		}
		dpx[0] = x[0];//第一颗往左砍 
		dpnum[0] = 1;
		for(int i=1;i<n;i++){
			if(x[i]-h[i]>dpx[i-1]){//左砍 
				dpx[i] = x[i];
				dpnum[i] = dpnum[i-1]+1;
			}else if(i+1==n){//最后一颗直接往右砍 
				
				dpx[i] = x[i];
				dpnum[i] = dpnum[i-1]+1;
			}else if(x[i]+h[i]<x[i+1]){//右砍 
				dpx[i] = x[i]+h[i];
				dpnum[i] = dpnum[i-1]+1;
				
			}else{//不砍 
				dpx[i] = x[i];
				dpnum[i] = dpnum[i-1];
			}
			
		}
		printf("%d\n",dpnum[n-1]);
		
	}	
}

猜你喜欢

转载自blog.csdn.net/qq_25955145/article/details/81260102
今日推荐