hd1505 dp优化 最大01矩阵

这题的话,求最大01矩阵,我们找每行的某一点,先初始化这点的高,再向两边延伸L[i],R[i],遍历所有节点就可以求出所有的面积

L[i]的求法可以用dp,一开始只看懂了用底*高的求法,一直在想dp在哪里...很好的题呀

状态转移方程

L[i] = L[L[i]-1] (a[k][i]<=a[k][L[i]-1])

先求出每行某一点的高度,剩下的问题和1506一模一样了

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>

using namespace std;

const int inf = (1<<31)-1;
const int MAXN = 1e3+10;

int dp[MAXN][MAXN];
int L[MAXN];
int R[MAXN];

int main()
{
    int t,n,m;
    char s[3];
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
              scanf("%s",s);
              if(s[0]=='F')dp[i][j] = dp[i-1][j] + 1;
              else dp[i][j] = 0;
            }
        }
        int ans,mmax = -inf;
        for(int i=1;i<=n;i++){
            dp[i][0] = dp[i][m+1] = -1;
            for(int j=1;j<=m;j++){
                L[j] = j;
                while(dp[i][j]<=dp[i][L[j]-1])
                    L[j] = L[L[j]-1]; //dp优化
            }
            for(int j=m;j>=1;j--){
                R[j] = j;
                while(dp[i][j]<=dp[i][R[j]+1])
                    R[j] = R[R[j]+1];

            }
            for(int j=1;j<=m;j++){
                ans = 3*dp[i][j]*(R[j]-L[j]+1);
                mmax = max(ans,mmax);
            }
        }
        cout<<mmax<<endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
}
View Code

 

posted @ 2016-04-13 14:47  iEdson  阅读(252)  评论(0编辑  收藏  举报