最大子矩形(SOJ3329)

来源:互联网 发布:淘宝哪些地方不包邮 编辑:程序博客网 时间:2024/05/21 05:24

(2012-04-27 14:03:25)

SOJ3329:http://cstest.scu.edu.cn/soj/problem.action?id=3329

这道题是让求最大子矩形,联想到之前做过的一道求最大正方形的一道题(SOJ2801当时那道题就是一个简单的DP)。所以刚开始我也考虑用动态规划来做,但想了好久还是没思路。后来搜了一些资料,这道题应该用极大化思想来解决。

代码:

#include<iostream>#include<cstring>#include<stack>using namespace std;int Left[1005][1005];int Right[1005][1005];int digit[1005][1005];int left_temp[1005][1005];int right_temp[1005][1005];int height[1005][1005];inline int min(int a,int b){    return a<b ? a : b;}inline int max(int a,int b){    return a>b ? a : b;}int main(){    int n,m;    int test;    scanf("%d",&test);    while(test--)    {        scanf("%d%d",&n,&m);        int i,j;        stack<pair<int,int> >temp;        for(i=1;i<=n;i++)        {            for(j=1;j<=m;j++)            {                scanf("%d",&digit[i][j]);                left_temp[i][j]=0;                right_temp[i][j]=m+1;            }            pair<int,int>xiao;            xiao.first=digit[i][1];            xiao.second=1;            temp.push(xiao);            for(j=2;j<=m;j++)            {                while(!temp.empty() && digit[i][j]>temp.top().first)                {                    right_temp[i][temp.top().second]=j;                    temp.pop();                }                xiao.first=digit[i][j];                xiao.second=j;                temp.push(xiao);            }            while(!temp.empty())                temp.pop();            xiao.first=digit[i][m];            xiao.second=m;            temp.push(xiao);            for(j=m-1;j>=1;j--)            {                while(!temp.empty() && digit[i][j]>temp.top().first)                {                    left_temp[i][temp.top().second]=j;                    temp.pop();                }                xiao.first=digit[i][j];                xiao.second=j;                temp.push(xiao);            }            while(!temp.empty())                temp.pop();        }        for(j=1;j<=m;j++)        {            Left[0][j]=0;            Right[0][j]=m+1;            height[0][j]=0;        }        for(i=1;i<=n;i++)            for(j=1;j<=m;j++)            {                if(digit[i][j]==1)                {                    Left[i][j]=0;                    Right[i][j]=m+1;                    height[i][j]=0;                }                else                {                    Left[i][j]=max(Left[i-1][j],left_temp[i][j]);                    Right[i][j]=min(Right[i-1][j],right_temp[i][j]);                    height[i][j]=height[i-1][j]+1;                }            }        int max=0;        for(i=1;i<=n;i++)            for(j=1;j<=m;j++)            {                int ye=height[i][j]*(Right[i][j]-Left[i][j]-1);                if(ye>max)                    max=ye;            }        printf("%d\n",max);    }    return 0;}

0 0
原创粉丝点击