• 【动态规划】创意吃鱼法


    原题传送门

    思路


    s1[i][j]表示(i,j)最多向左(或向右)延伸多少个格子,使这些格子中的数都是0(不包括(i,j));
    s2[i][j]表示(i,j)最多向上(或向下)延伸多少个格子,使这些格子中的数都是0(不包括(i,j));
    f[i][j]表以(i,j)为右下角(或左下角)的最大对角线长度。

    状态转移方程:f[i][j]=min(f[i-1][j-1],min(s1[i][j-1],s2[i-1][j]))+1

    Code


    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<map>
    typedef long long ll;
    using namespace std;
    int n,m,ans;
    int a[2509][2509],f[2509][2509],s1[2509][2509],s2[2509][2509];//s1为横向,s2为纵向 
    int main()
    {
        cin>>n>>m;
        //第一遍左上——右下 
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
            if(!a[i][j])
            {
                s1[i][j]=s1[i][j-1]+1;
                s2[i][j]=s2[i-1][j]+1;
            }
            if(a[i][j])
            f[i][j]=min(f[i-1][j-1],min(s1[i][j-1],s2[i-1][j]))+1;
            ans=max(ans,f[i][j]);
        }
        //第二遍右上——左下 
        memset(f,0,sizeof(f)); 
        memset(s1,0,sizeof(s1));//数组置0 
        memset(s2,0,sizeof(s2)); 
        for(int i=1;i<=n;i++)
        for(int j=m;j>=1;j--)
        {
            if(!a[i][j])
            {
                s1[i][j]=s1[i][j+1]+1;
                s2[i][j]=s2[i-1][j]+1;
            }
            if(a[i][j])
            f[i][j]=min(f[i-1][j+1],min(s1[i][j+1],s2[i-1][j]))+1;
            ans=max(ans,f[i][j]);
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    NYIST 46 最少乘法次数
    OpenSSL命令---rsa
    Javah生成JNI头文件
    Stbdroid之ShapeDrawable
    Android之判断设备网络连接状态,并判断连接方式
    [置顶] 程序员必知(二):位图(bitmap)
    中断子系统8_软中断入口处理
    二叉搜索树的后续遍历序列
    整理生命
    sicily9162. RAZLIKA
  • 原文地址:https://www.cnblogs.com/gongdakai/p/11215388.html
Copyright © 2020-2023  润新知