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

    题目描述

    回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*)。她发现,把大池子视为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都是 都是线性dp 最后取值一般为dp【n】

    而图的dp有些会有不同 主要关注i j这个点 而不是 1-i 1-j 这个范围 并且最值边dp边更新
    这题的dp为 以i j为左(右 )下角的最大对角线长度
    注意要dp两遍
    #include<bits/stdc++.h>
    using namespace std;
    //input
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m);
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define LL long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define N 2500+5
    #define inf 0x3f3f3f3f
    int mp[N][N];
    int dp[N][N];
    int main()
    {
        int n,m;
        RII(n,m);
        rep(i,1,n)
        rep(j,1,m)
        RI(mp[i][j]);
    
        int ans=0;
        rep(i,1,n)
        rep(j,1,m)
        if(mp[i][j])
        {
            int s1=0,s2=0;
            for(int k=i-1;k>=1;k--)
                if(!mp[k][j])s1++;
                else break;
            for(int k=j-1;k>=1;k--)
                if(!mp[i][k])s2++;
                else break;
            dp[i][j]=min(dp[i-1][j-1],min(s1,s2))+1;
            if(dp[i][j]>ans)ans=dp[i][j];
        }
    
        rep(i,1,n)
        for(int j=m;j>=1;j--)
        if(mp[i][j])
        {
            int s1=0,s2=0;
            for(int k=i-1;k>=1;k--)
                if(!mp[k][j])s1++;
                else break;
            for(int k=j+1;k<=m;k++)
                if(!mp[i][k])s2++;
                else break;
            dp[i][j]=min(dp[i-1][j+1],min(s1,s2))+1;
            if(dp[i][j]>ans)ans=dp[i][j];
        }
        cout<<ans;
    }


  • 相关阅读:
    常州day2
    常州day3
    常州day1p3
    第3章 图像基础
    第2章 什么是深度学习?
    Deep Learning for Computer Vision with Python 第1章:整个内容简介
    双目视觉(1)---立体匹配介绍
    ubuntu 16.04 配置python远程jupyter nootbook环境
    Ubuntu16.04 Caffe CPU版本 安装步骤记录
    opencv(2)- 处理像素值
  • 原文地址:https://www.cnblogs.com/bxd123/p/10518890.html
Copyright © 2011-2022 走看看