codeforces 545C woodcutters ---- dp

题目链接 https://vjudge.net/contest/214177#problem/C

题意:给定n棵树的坐标x和高度h,要求砍树,树砍倒后向左或向右躺在地上时,占的区间不能含有别的树,问最多砍多少树。

题解:dp[i][0]表示第i棵树不动,dp[i][1]表示i棵树向左倒在地上,dp[i][2]表示向右倒,dp的转移方程见代码

#include 
using namespace std;
typedef long long ll;
int n;
const int maxn = 1e5+10;
ll x[maxn], h[maxn];
int dp[maxn][5];


int main() {
    scanf("%d", &n);
    for(int i = 1;i <= n;i++) {
        scanf("%lld%lld", &x[i], &h[i]);
    }
    
    
    if(n == 1) {
        printf("%d\n", 1);
        return 0;
    } 
    if(x[1]+h[1] < x[2])
        dp[1][2] = 1;
    dp[1][1] = 1;
        
    for(int i = 2;i <= n;i++) {
        int p1 = dp[i-1][0];
        int p2 = dp[i-1][1];
        int p3 = dp[i-1][2];
        dp[i][0] = max(p1, p2);
        dp[i][0] = max(dp[i][0], p3);
        if(x[i]-x[i-1] > h[i]+h[i-1]) {
            dp[i][1] = dp[i][0] + 1;
        } else if(x[i]-x[i-1] > h[i]) {
            dp[i][1] = 1 + max(p1, p2);
        } 
        if(i+1 <= n && x[i+1]-x[i] > h[i]) {
            dp[i][2] = 1 + dp[i][0];
        }
        if(i == n) {
            dp[i][2] = 1 + dp[i][0];
        }
    }
    
    
    
    printf("%d\n", max(dp[n][2], max(dp[n][0], dp[n][1])));
   
    return 0;
}

// dp 0 1 2 
// 1    1 0
// 2  1   2 
// 3  2  
// 4  2 
// 5  2 3 3

 

你可能感兴趣的:(动态规划)