HDU 1506 && HDU1505 && HDU 2870 (DP).

~~~~

这三道DP题是逐层递进的,大家可以从前往后做。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1506

http://acm.hdu.edu.cn/showproblem.php?pid=1505

http://acm.hdu.edu.cn/showproblem.php?pid=2870

~~~~

1506:

分别找每一块板子的可以的最左边界和最右边界,注意这时不能用两个for暴力(显然会TLE),所以要用DP的思想边搜边保存。

另外注意的是要用long long.

#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 111111
#define ll __int64
using namespace std;

struct node
{
    int l,r;
    ll h;   //~~
}q[N];

int main()
{
    int n;
    while(~scanf("%d",&n),n)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%I64d",&q[i].h);
            q[i].l=q[i].r=i;
        }
        q[0].h=q[n+1].h=-1;
        for(int i=2;i<=n;i++)   //左边界
            while(q[i].h<=q[q[i].l-1].h) q[i].l=q[q[i].l-1].l;
        for(int i=n-1;i>0;i--)  //右边界
            while(q[i].h<=q[q[i].r+1].h) q[i].r=q[q[i].r+1].r;
        ll ans=0;
        for(int i=1;i<=n;i++)
            ans=max(q[i].h*(q[i].r-q[i].l+1),ans); //高度*区间长即得结果
        printf("%I64d\n",ans);
    }
    return 0;
}

~~~~

HDU 1505:

相对1506来说,1505只是需要多加一步逐层计算便可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#define N 1111
#define INF
using namespace std;

int g[N][N],l[N],r[N],v[N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                char c[5];
                scanf("%s",c);
                if(c[0]=='R') g[i][j]=0;
                else g[i][j]=1;
            }
        }
        int ans=-1;
        memset(v,0,sizeof(v));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(g[i][j]) v[j]++;     //~~
                else v[j]=0;        //~~
                l[j]=r[j]=j;
            }
            v[0]=v[m+1]=-1;
            for(int j=2;j<=m;j++)
                while(v[j]<=v[l[j]-1]) l[j]=l[l[j]-1];
            for(int j=m-1;j>0;j--)
                while(v[j]<=v[r[j]+1]) r[j]=r[r[j]+1];
            for(int j=1;j<=m;j++)
            {
                int res=v[j]*(r[j]-l[j]+1);
                ans=max(ans,res);
            }
        }
        printf("%d\n",ans*3);
    }
    return 0;
}

~~~~

2870:

a,w,y,z一组,b,w,x,z一组,c,x,y,z一组,分别转换为a,b,c,就是1505的问题了。三次DP操作即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#define N 1111
using namespace std;

int n,m,ans;
int l[N],r[N];
int g[N][N];
char str[N][N];
void dp()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            l[j]=r[j]=j;
        g[i][0]=g[i][m+1]=-1;
        for(int j=2;j<=m;j++)
            while(g[i][j]<=g[i][l[j]-1]) l[j]=l[l[j]-1];
        for(int j=m-1;j>0;j--)
            while(g[i][j]<=g[i][r[j]+1]) r[j]=r[r[j]+1];
        for(int j=1;j<=m;j++)
            ans=max(ans,g[i][j]*(r[j]-l[j]+1));
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        ans=-1;
        for(int i=1;i<=n;i++)
            scanf("%s",str[i]+1);//~~
        memset(g,0,sizeof(g));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(str[i][j]=='a'||str[i][j]=='w'||str[i][j]=='y'||str[i][j]=='z')
                    g[i][j]=g[i-1][j]+1;//~~
                else
                    g[i][j]=0;  //~~
        dp();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(str[i][j]=='b'||str[i][j]=='w'||str[i][j]=='x'||str[i][j]=='z')
                    g[i][j]=g[i-1][j]+1;
                else
                    g[i][j]=0;
        dp();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(str[i][j]=='c'||str[i][j]=='y'||str[i][j]=='x'||str[i][j]=='z')
                    g[i][j]=g[i-1][j]+1;
                else
                    g[i][j]=0;
        dp();
        printf("%d\n",ans);
    }
    return 0;
}

HDU 1506 && HDU1505 && HDU 2870 (DP).

时间: 2024-10-17 19:09:28

HDU 1506 && HDU1505 && HDU 2870 (DP).的相关文章

hdu 5623 KK&#39;s Number(dp)

问题描述 我们可爱的KK有一个有趣的数学游戏:这个游戏需要两个人,有N\left(1\leq N\leq 5*{10}^{4} \right)N(1≤N≤5∗10?4??)个数,每次KK都会先拿数.每次可以拿任意多个数,直到NN个数被拿完.每次获得的得分为取的数中的最小值,KK和对手的策略都是尽可能使得自己的得分减去对手的得分更大.在这样的情况下,最终KK的得分减去对手的得分会是多少? 输入描述 第一行一个数T\left( 1\leq T\leq 10\right)T(1≤T≤10),表示数据组

HDU 4968 Improving the GPA(dp)

HDU 4968 Improving the GPA 题目链接 dp,最大最小分别dp一次,dp[i][j]表示第i个人,还有j分的情况,分数可以减掉60最为状态 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int t, avg, n; double dp1[15][405], dp2[15][405]; double get(int x) { if

2014多校第七场1005 || HDU 4939 Stupid Tower Defense (DP)

题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害. 蓝塔 : 经过该塔所在单位之后,再走每个单位长度的时候时间会变成t+z. 思路 : 官方题解 : 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define LL long long

HDU 5617 Jam&#39;s maze(DP)

题目链接:点击打开链接 题意:给你一个n*n的矩阵.  求从(1,1)走到(n,n)所组成的回文串个数. 思路:一开始傻逼把状态写成了d[x][y][s],s表示一个串, 用map存的, 后来发现极不可行, 因为这个状态简直太大了, 包括了s串的所有情况. 只是相当于一个dfs中的剪枝罢了. 后来想到, 其实串是不必记录的, 我们只要统计个数, 所以不妨在DP的过程中就判断回文串的情况, 那么就需要同时记录两头的情况.  为了不爆内存, 将状态表示成d[i][x1][x2], 表示走了i步, 左

hdu 4960 Another OCD Patient(dp)2014多校训练第9场

Another OCD Patient                                                                         Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) pat

2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)

题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位与的值相同,问能找出多少符合要求的组合. 思路 :比赛的时候有点没有头绪,后来二师兄想出了状态转移方程,YN又改了很多细节,最后才A的.总之是个别扭的DP..... 一开始是 _xor[i][j^a[i]] += _xor[i-1][j] :j 的下一个状态 就是异或上a[i],这个数组所代表的意思

2014多校第一场 E 题 || HDU 4865 Peter&#39;s Hobby (DP)

题目链接 题意 : 给你两个表格,第一个表格是三种天气下出现四种湿度的可能性.第二个表格是,昨天出现的三种天气下,今天出现三种天气的可能性.然后给你这几天的湿度,告诉你第一天出现三种天气的可能性,让你求出最可能出现的天气序列 . 思路 : 定义第 i 天叶子湿度为hum[i].第 i 天,天气为 j 的最大概率为dp[i][j].wealea[i][j]表示天气为 i 叶子为j的概率,weawea[i][j]表示今天天气为 i 明天天气为j的概率,st[i]表示第一天天气为i的概率.pre[i]

HDU 1231——最大连续子序列(DP)

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18603    Accepted Submission(s): 8268 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j

HDU 1003:Max Sum(DP)

Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 142742    Accepted Submission(s): 33225 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max s