1 /*
2 题意:每棵树给出坐标和高度,可以往左右倒,也可以不倒
3 问最多能砍到多少棵树
4 DP:dp[i][0/1/2] 表示到了第i棵树时,它倒左或右或不动能倒多少棵树
5 分情况讨论,若符合就取最大值更新,线性dp,自己做出来了:)
6 */
7 #include <cstdio>
8 #include <algorithm>
9 #include <cstring>
10 #include <cmath>
11 #include <iostream>
12 using namespace std;
13
14 typedef long long LL;
15
16 const int MAXN = 1e5 + 10;
17 const int INF = 0x3f3f3f3f;
18 LL x[MAXN], h[MAXN];
19 LL dp[MAXN][3]; //0-l 1-no 2-r
20
21 int main(void) //Codeforces Round #303 (Div. 2) C. Woodcutters
22 {
23 //freopen ("C.in", "r", stdin);
24
25 int n;
26 while (scanf ("%d", &n) == 1)
27 {
28 for (int i=1; i<=n; ++i)
29 {
30 scanf ("%I64d%I64d", &x[i], &h[i]);
31 }
32 memset (dp, 0, sizeof (dp));
33 dp[1][0] = dp[1][1] = 1;
34 if (x[1] + h[1] < x[2]) dp[1][2] = 1;
35 for (int i=2; i<=n; ++i)
36 {
37 LL tmp;
38 tmp = max (dp[i-1][0], dp[i-1][1]);
39 tmp = max (tmp, dp[i-1][2]);
40 dp[i][1] = tmp;
41 if (x[i] - h[i] > x[i-1])
42 {
43 dp[i][0] = max (dp[i-1][0], dp[i-1][1]) + 1;
44 }
45 if (x[i] - x[i-1] > h[i-1] + h[i])
46 {
47 dp[i][0] = max (dp[i][0], dp[i-1][2] + 1);
48 }
49 if (i < n && x[i] + h[i] < x[i+1])
50 {
51 dp[i][2] = tmp + 1;
52 }
53 if (i == n) dp[i][2] = tmp + 1;
54 }
55
56 LL ans;
57 ans = max (dp[n][0], dp[n][1]);
58 ans = max (ans, dp[n][2]);
59 printf ("%I64d\n", ans);
60 }
61
62 return 0;
63 }
DP Codeforces Round #303 (Div. 2) C. Woodcutters
原文:http://www.cnblogs.com/Running-Time/p/4520914.html