zoukankan      html  css  js  c++  java
  • P1736 创意吃鱼法

    题目描述 
    回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*)。她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略。

    在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵“对角线的一端”下口,只一吸,就能把对角线上的那一队鲜鱼吸入口中。

    猫猫是个贪婪的家伙,所以她想一口吃掉尽量多的鱼。请你帮猫猫计算一下,她一口下去,最多可以吃掉多少条鱼?

    输入输出格式 
    输入格式: 
    有多组输入数据,每组数据:

    第一行有两个整数n和m(n,m≥1),描述池塘规模。接下来的n行,每行有m个数字(非“0”即“1”)。每两个数字之间用空格隔开。

    对于30%的数据,有n,m≤100

    对于60%的数据,有n,m≤1000

    对于100%的数据,有n,m≤2500

    输出格式: 
    只有一个整数——猫猫一口下去可以吃掉的鱼的数量,占一行,行末有回车。

    输入输出样例 
    输入样例#1: 复制 
    4 6 
    0 1 0 1 0 0 
    0 0 1 0 1 0 
    1 1 0 0 0 1 
    0 1 1 0 1 0 
    输出样例#1: 复制 
    3

    dp 
    这题跟正方形dp那题的升级版 
    这里写图片描述

    怎么更新呢?

    一方面: 
    左上角那个黄点为前一个状态

    另一个限制方面: 
    左边和上面的那两个黄点开始按箭头方向走,分别统计各自最长0的个数(开s1,s2数组进行记忆化)

    取这三者的最小值就行

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

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 2600
    #define inf 0x3f3f3f
    
    typedef long long ll;
    
    int n,m;
    int G[maxn][maxn];
    int dp[maxn][maxn];
    int s1[maxn][maxn];
    int s2[maxn][maxn];
    int ans=0;
    
    int main()
    {
        scanf("%d %d",&n,&m);
    
        //从左上至右下    
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
            {
                scanf("%d",&G[i][j]);
                if(!G[i][j])//为0就进行增长处理
                {
                    s1[i][j]=s1[i][j-1]+1; 
                    s2[i][j]=s2[i-1][j]+1;
                }
                else
                {
                    dp[i][j]=min(dp[i-1][j-1],min(s1[i][j-1],s2[i-1][j]))+1;
                    ans=max(ans,dp[i][j]);
                }
            }
        memset(dp,0,sizeof(dp));
        memset(s1,0,sizeof(s1));
    
        //从右上至左下,就改一点点就行
        for(int i=1; i<=n; i++)
            for(int j=m; j>=1; j--)
            {
                if(!G[i][j])
                    s1[i][j]=s1[i][j+1]+1;
                else
                {
                    dp[i][j]=min(dp[i-1][j+1],min(s1[i][j+1],s2[i-1][j]))+1;
                    ans=max(ans,dp[i][j]);
                }
            }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    android 75 新闻列表页面
    android 74 下载文本
    android 73 下载图片
    android 72 确定取消对话框,单选对话框,多选对话框
    android 71 ArrayAdapter和SimpleAdapter
    android 70 使用ListView把数据显示至屏幕
    maven如何将本地jar安装到本地仓库
    Centos6.7搭建ISCSI存储服务器
    解决maven打包编译出现File encoding has not been set问题
    MySQL 解决 emoji表情 的方法,使用utf8mb4 字符集(4字节 UTF-8 Unicode 编码)
  • 原文地址:https://www.cnblogs.com/planche/p/8438150.html
Copyright © 2011-2022 走看看