zoukankan      html  css  js  c++  java
  • CF545C Woodcutters

    CF545C Woodcutters

    洛谷传送门

    题意翻译

    给 n 棵树在一维数轴上的坐标,以及它们的长度。现在要你砍倒 这些树,树可以向左倒也可以向右倒,砍倒的树不能重合、当然 也不能覆盖其他的树原来的位置,现在求最大可以砍倒的树的数 目。 1 <= n <= 10^5 ; 1 <= x i , h i <= 10^9

    感谢@凉凉 提供的翻译


    题解:

    一眼切的DP。

    看到很多大佬都是用的贪心解法。所以来介绍一下DP。

    DP的精髓在于转移。所以状态的设置要为转移服务。转移要保证无后效性和最优子结构。DP就是这些东西,再也没有什么其他的了。什么答案的统计都是细节问题。

    那么这道题显然,针对于两棵树之间的转移,一定有第(i)棵树不砍、往左砍、往右砍这三种状态,每种状态都会对应一个最优决策,所以就直接按这个设状态:(dp[i][0/1/2])

    然后按题意转移就行。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    int n,dp[maxn][3];
    struct tree
    {
    	int x,h;
    }t[maxn];
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	    scanf("%d%d",&t[i].x,&t[i].h);
    	dp[1][0]=1;
        if(t[2].x-t[1].x>t[1].h) 
            dp[1][1]=1;
    	for(int i=2;i<=n;i++)
    	{
    		dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
    		if(t[i].x-t[i-1].x>t[i-1].h) 
                dp[i][0]=max(dp[i][0],dp[i-1][2]);
    		if(t[i].x-t[i-1].x>t[i].h) 
                dp[i][1]=max(dp[i-1][1]+1,dp[i-1][0]+1);
    		if(t[i].x-t[i-1].x>t[i].h+t[i-1].h) 
                dp[i][1]=max(dp[i][1],dp[i-1][2]+1);
    		dp[i][2]=max(dp[i-1][0],dp[i-1][1])+1;
    		if(t[i].x-t[i-1].x>t[i-1].h) 
                dp[i][2]=max(dp[i][2],dp[i-1][2]+1);
    	}
    	cout<<max(max(dp[n][0],dp[n][1]),dp[n][2]);
    	return 0;
    }
    
  • 相关阅读:
    Linux常用命令
    IBM Java多线程 1. 线程基础
    IBM Java多线程 6.其它线程 API 详细信息
    Jakarta Commons Logging学习笔记
    Linux 下存放ssh信息的文件位置
    ArrayList的使用方法
    JAVA基础--JAVA中的反射机制详解
    使用 Bash shell脚本进行功能测试
    log4j详细解
    Eclipse Template用法探讨
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14037643.html
Copyright © 2011-2022 走看看