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 }
时间: 2024-08-06 03:45:17