zoukankan      html  css  js  c++  java
  • 【动态规划】创意吃鱼法

    原题传送门

    思路


    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;
    }
    
  • 相关阅读:
    C++中类模板的概念和意义
    欢迎访问新博客aiyoupass.com
    P2327
    P2885
    P1968
    Link-Cut-Tree
    树的重心
    点分治笔记
    SPOJ 375
    树链剖分
  • 原文地址:https://www.cnblogs.com/gongdakai/p/11215388.html
Copyright © 2011-2022 走看看