Codeblocks 574D,DP

来源:互联网 发布:二叉树的深度算法 编辑:程序博客网 时间:2024/04/30 02:29

题意:

给出n摞箱子,它们紧挨着放在一起,现在有如下操作:每轮,每次把暴露的箱子拿去(对于暴露的定义:左、右、上三个面中,只要有一个面没跟箱子挨着,则暴露),问,经过多少轮后,箱子被拿光。

数据范围:箱子数量0<n<=10^5,箱子高度0<h<=10^9。

分析:

每轮,一摞箱子受到的影响,h[i]=max(h[i-1],h[i]-1,h[i+1]),拿光它,需要的操作轮数:num[i]=min(num[i-1]+1,h[i],num[i+1]+1)。

每摞箱子被拿光总共有三种方式:

①左边箱子拿光了;dp[i]=dp[i-1]+1;

②右边箱子拿光了;dp[i]=dp[i+1]+1;

③或者是因为自己顶面暴露,而被每次拿一个,最后拿光;dp[i]=h[i];

实现过程,只需正序DP一次,逆序DP一次。

具体实现代码:

#include<cstdio>#include<algorithm>#include<iostream>#include<vector>using namespace std;#define N 100010typedef long long LL;int dp[N],h[N],n;int main(){    while(scanf("%d",&n)!=EOF)    {        h[0]=0;        for(int i=1;i<=n;i++)        {            scanf("%d",&h[i]);        }        dp[0]=0;        for(int i=1;i<=n;i++)        {            dp[i]=min(h[i],dp[i-1]+1);        }        dp[n+1]=0;        int ans=0;        for(int i=n;i>0;i--)        {            dp[i]=min(dp[i],dp[i+1]+1);            ans=max(ans,dp[i]);        }        cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击