hdu1506 经典dp

来源:互联网 发布:淘宝仓管的工作 编辑:程序博客网 时间:2024/05/20 06:10

hdu1506 经典dp

刚开始刷dp的题,看到这题,就知道是dp题,因为我就是因为这是dp题才来做的,我知道这是dp题,然后就没了,


一脸懵逼啊  做了几道背包dp,一做不是背包题就不会做了 ,只知道设f[i],f[i]代表的意思都是错的,

在做这种题时我只知道直接用状态直接求解答案,然而。。。。开始时连问题都没有搞清楚,开始时应该搞清楚解题步骤 因该清晰去推倒答案 一步一步的解 比如说这个题 问题是求最大面积 首先是高和宽  最直白解就是枚举每个点 然后判断前后有多少个连续高于他的下标,由于数字大 ,不能有普通法 所以要用dp记忆 while(tt>1&&a[i]<=a[tt-1]) tt=l[tt-1];    l[i]表示左左边连续大于啊a[i]的下标 

这个其实在kmp中有所体现 居然没有想到(哭)

#include<iostream>#include<cstdlib>#include<stdio.h>#define LL long long#define Max(a,b) a>b?a:busing namespace std;const int N=100010;LL  a[N],l[N],r[N],maxn,s;int main(){    int n;    while(scanf("%d",&n) && n)    {        for(int i=1;i<=n;i++)        scanf("%I64d",&a[i]);        l[1]=1;r[n]=n;        for(int i=2;i<=n;i++)        {            int tt=i;            while(tt>1&&a[i]<=a[tt-1]) tt=l[tt-1];///dp思想            l[i]=tt;        }        for(int i=n-1;i>=1;i--)        {            int tt=i;            while(tt<n&&a[i]<=a[tt+1]) tt=r[tt+1];            r[i]=tt;        }        maxn=0;        for(int i=1;i<=n;i++)            maxn=Max(maxn,(r[i]-l[i]+1)*a[i]);        printf("%I64d\n",maxn);    }    return 0;}


1 0
原创粉丝点击