hdu1505 dp

  1 //Accepted    5196 KB    109 ms
  2 //类似hdu1506
  3 //输入数据的格式没有明确的限制
  4 //可能出现以下情况
  5 //5 5
  6 //R
  7 //F
  8 //F F F
  9 //F F F F F
 10 //R R R
 11 //R R
 12 //R F R F R
 13 //R R R R R
 14 #include <cstdio>
 15 #include <cstring>
 16 #include <iostream>
 17 using namespace std;
 18 const int imax_n = 1005;
 19 bool map[imax_n][imax_n];
 20 int a[imax_n][imax_n];
 21 int l[imax_n],r[imax_n];
 22 int n,m;
 23 void getA()
 24 {
 25     for (int i=1;i<=n;i++)
 26     {
 27         for (int j=1;j<=m;j++)
 28         {
 29             a[i][j]=0;
 30             int t=i;
 31             while (t>0 && map[t][j]==1)
 32             {
 33                 a[i][j]++;
 34                 t--;
 35             }
 36         }
 37     }
 38    // for (int i=1;i<=n;i++)
 39     //{
 40     //    for (int j=1;j<=m;j++)
 41     //    printf("%d ",a[i][j]);
 42     //    printf("\n");
 43     //}
 44 }
 45 void Dp()
 46 {
 47     getA();
 48     int ans=0;
 49     for (int i=1;i<=n;i++)
 50     {
 51         l[1]=1;
 52         a[i][0]=-1;
 53         for (int j=2;j<=m;j++)
 54         {
 55             int t=j;
 56             while (a[i][j]<=a[i][t-1])
 57             {
 58                 t=l[t-1];
 59             }
 60             l[j]=t;
 61         }
 62         r[m]=m;
 63         a[i][m+1]=-1;
 64         for (int j=m-1;j>=1;j--)
 65         {
 66             int t=j;
 67             while (a[i][j]<=a[i][t+1])
 68             {
 69                 t=r[t+1];
 70             }
 71             r[j]=t;
 72         }
 73         for (int j=1;j<=m;j++)
 74         if (a[i][j]*(r[j]-l[j]+1)>ans)
 75         ans=a[i][j]*(r[j]-l[j]+1);
 76     }
 77     printf("%d\n",3*ans);
 78 }
 79 char s[5];
 80 int main()
 81 {
 82     int T;
 83     while (scanf("%d",&T)!=EOF)
 84     {
 85         while (T--)
 86         {
 87             scanf("%d%d",&n,&m);
 88             for (int i=1;i<=n;i++)
 89             {
 90                 for (int j=1;j<=m;j++)
 91                 {
 92                     scanf("%s",s);
 93                     if (s[0]==‘F‘)
 94                     map[i][j]=1;
 95                     else
 96                     map[i][j]=0;
 97                 }
 98             }
 99         //for (int i=1;i<=n;i++)
100         //{
101          //   for (int j=1;j<=m;j++)
102          //   printf("%d",map[i][j]);
103          //   printf("\n");
104         //}
105             Dp();
106         }
107     }
108     return 0;
109 }

hdu1505 dp

时间: 2024-08-26 05:04:56

hdu1505 dp的相关文章

HDU 1506 &amp;&amp; HDU1505 &amp;&amp; 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的思想边搜边保存. 另外注

hdu1505(dp求最大子矩阵)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1505 分析: 这题是HDU 1506 的加强版,定义一个二维数组,d[i][j]表示第i行j列元素在前i行中的最大高度.(以第一行为底)例如测试样例: 0 1 1 1 1 1                                                 0 1 1 1 1 1 1 1 1 1 1 1           (F=1,R=0,方便求和)        1 2 2 2 2

DP总结 ——QPH

常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一头压入元素. 队列中维护的是两个值.一个是位置,这和k的范围有关系,另外一个是f(k)的值,这个用来维护单调性,当然如果f(k)的值可以利用dp值在O(1)的时间内计算出来的话队列中可以只维护一个表示位置的变量. 枚举到一个i的时候,首先判断队首元素的位置是否已经不满足k的范围了,如果不满足就将队首

HDU1505(HDU1506的加强版)

昨天打 CF又跪了,最近睡不好睡不好睡不好-感觉整个人都累傻了,根本无办法写下去,仅仅写了一题签到题就跪了orz..从未试过这么悲剧. 今天早上凭着我的意念("怨念"),七点又起来了!我已经连续好多天七点自动起来(不是自然醒,是意念,是意念....),刷啊刷啊刷dp. 今天刷的是昨天的加强版,实际上就多了一个for循环,和做高度处理,不直到是不是正解(  ╮(╯▽╰)╭ ),但是AC就好了... 经过多次调试我的shell脚本,这个acm.sh算是比较稳定了,还差一个自动提交机啊!我的

HDU 2870 Largest Submatrix(DP)

题意  求最大相同字符子矩阵  其中一些字符可以转换 其实就是HDU1505 1506的加强版  但是分了a,b,c三种情况  看哪次得到的面积最大 对于某一个情况  可以把该字符和可以转换为该字符的位置赋值0 其它位置赋值1 这样就转化成了求最大全0矩阵的问题了 对于转换后矩阵中的每个点 看他向上有多少个连续0 把这个值存在h数组中 再用l数组和r数组记录h连续大于等于该位置的最左边位置和最右位置 这样包含(i,j)点的最大矩阵面积就是(r[i][j]-l[i][j]+1)*h[i][j] 面

杭电dp题集,附链接

Robberies 点击打开链接 背包;第一次做的时候把概率当做背包(放大100000倍化为整数):在此范围内最多能抢多少钱  最脑残的是把总的概率以为是抢N家银行的概率之和- 把状态转移方程写成了f[j]=max{f[j],f[j-q[i].v]+q[i].money}(f[j]表示在概率j之下能抢的大洋); 正确的方程是:f[j]=max(f[j],f[j-q[i].money]*q[i].v)  其中,f[j]表示抢j块大洋的最大的逃脱概率,条件是f[j-q[i].money]可达,也就是

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&