创意吃鱼(题解)

题目描述


可爱猫猫家里长方形大池子中有很多鱼,她开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*)。她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略。

在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵“对角线的一端”下口,只一吸,就能把对角线上的那一队鲜鱼吸入口中。    猫猫是个贪婪的家伙,所以她想一口吃掉尽量多的鱼。请你帮猫猫计算一下,她一口下去,最多可以吃掉多少条鱼?

思路


这是一道比较基础的计数类二维DP
x[i][j]表示(i,j)最多向左(或右)延伸多少个格子,使这些格子中的数都是0(不包括(i,j))

y[i][j]表示(i,j)最多向上延伸多少个格子,使这些格子中的数都是0(不包括(i,j))

f[i][j]表以(i,j)为右下(左下)角的最大对角线长度

方程: f [ i ] [ j ] = m i n ( f [ i 1 ] [ j 1 ] , m i n ( s 1 [ i ] [ j 1 ] , s 2 [ i 1 ] [ j ] ) ) + 1 ;

代码:

 //By Bibi
///                 .-~~~~~~~~~-._       _.-~~~~~~~~~-.
///             __.'              ~.   .~              `.__
///           .'//                  \./                  \\`.
///        .'//                     |                     \\`.
///       .'// .-~"""""""~~~~-._     |     _,-~~~~"""""""~-. \\`.
///     .'//.-"                 `-.  |  .-'                 "-.\\`.
///   .'//______.============-..   \ | /   ..-============.______\\`.
/// .'______________________________\|/______________________________`.
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
const int MAXN=2510;
int read(){
    int sum=0,flag=1;
    char c;
    for(;c<'0'||c>'9';c=getchar())if(c=='-') flag=-1;
    for(;c>='0'&&c<='9';c=getchar())sum=(sum<<1)+(sum<<3)+c-'0';
    return sum*flag;
}
int n,m;
int maxx=0;
int a[MAXN][MAXN];
int x[MAXN][MAXN],y[MAXN][MAXN];
int f[MAXN][MAXN];
void init(){
    n=read();m=read();
    rep(i,1,n) rep(j,1,m)  a[i][j]=read();  
}
void DP(){
    rep(i,1,n)
    rep(j,1,m){
        if(!a[i][j]){
            x[i][j]=x[i-1][j]+1;
            y[i][j]=y[i][j-1]+1;
        }
        else {
            f[i][j]=min(f[i-1][j-1],min(y[i][j-1],x[i-1][j]))+1;
        }
        maxx=max(maxx,f[i][j]);
    }
        memset(f,0,sizeof f);
        memset(x,0,sizeof x);
        memset(y,0,sizeof y);
        rep(i,1,n)
        dep(j,m,1){
            if(!a[i][j]){
            x[i][j]=x[i-1][j]+1;
            y[i][j]=y[i][j+1]+1;
        }
        else {
            f[i][j]=min(f[i-1][j+1],min(y[i][j+1],x[i-1][j]))+1;

        }
        maxx=max(maxx,f[i][j]);
        }
}
int main(){
    init();
    DP();
    printf("%d",maxx);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/bbbblzy/article/details/80287008