【洛谷】 P1387 最大正方形(dp,滚动数组)

今天比赛的时候写的是前缀和,开了三个二维的数组,然后比赛的那道题只给了8MB内存,于是就愉快的MLE了。
然后学习了一下大佬的滚动数组写法,竟然只要一个 2 m a x n 的dp数组,震惊。。。

其实原理就是dp只基于当前行和上一行的状态,于是我们只用保存这两行的信息就可以了。
状态转移方程:

d p [ i   &   1 ] [ j ] = m i n {   d p [ i   &   1 ] [ j 1 ] , m i n { d p [ i   &   1 ] [ j ] , d p [ i   &   1 ] [ j 1 ]   } + 1

其中 i & 1 i & 1 就是数组滚动的关键了,利用的就是 i 的奇偶性。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2100;
int dp[2][maxn];
int main(){
    int n,m,ans = 0,x;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%d",&x);
            if(x == 1)  dp[i&1][j] = min(dp[i&1][j-1],min(dp[~i&1][j],dp[~i&1][j-1])) + 1;
            else    dp[i&1][j] = 0;
            ans = max(ans,dp[i&1][j]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41009682/article/details/81613084