您的位置:首页 > 其它

Codeblocks 574D,DP

2015-08-31 22:07 162 查看
题意:

给出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 100010
typedef long long LL;
int dp
,h
,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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: