zoukankan      html  css  js  c++  java
  • hdu4846 最大子正方形(dp)

    题意:
          给你一个图,让你找到最大的子矩形。
    思路:

          之前做过一个最大子矩阵,记得当时是用三种方法做的,两种都是瓶颈法,第三种是dp,结果今天的用瓶颈吧怎么都过不去,哎!不知道为什么,后来没办法有写了和dp顺利ac了,我们求最大子矩阵的时候是记录最大的长*宽,这次只要记录最大的min(长,宽),就行了,说下这个题目的dp做法吧,只要是开三个数组,L[],R[],sum[],sum是记录当前点的上面有多少个连续的1,L是记录当前点sum大于等于左边的最远的那个数的下标(连续大于),R则是又边,则我们可以一边更新sum一边更新L,R和ans,主要核心如下


    for(i = 1 ;i <= n ;i ++)
    {
       for(j = 1 ;j <= n ;j ++)
       map[i][j] == '.' ? sum[j] ++ : sum[j] = 0;//更新当前点上面有多少个连续1
       //更新当前点左边连续大于的最远
       L[1] = 1;
       for(j = 2 ;j <= n ;j ++)
       {
          int k = j;
          while(k > 1 && sum[j] <= sum[k-1]) k = L[k-1];
          L[j] = k;
       }
      //更新当前点右边连续大于的最远
       R[1] = n;
       for(j = n - 1 ;j >= 1 ;j --)
       {
          int k = j;
          while(k > 1 && sum[j] <= sum[k+1]) k = R[k+1];
          R[j] = k;
       }
      // 更新答案
      for(j = 1 ;j <= n ;j ++)
      {
         int now = min(R[j] - L[j] + 1 ,sum[j]);
         if(ans < now) ans = now;
      }
    }  

    ok核心就是这些,时间复杂度是O(n^2)


    #include<stdio.h>
    #include<string.h>
    
    int L[1111] ,R[1111] ,sum[1000];
    int map[1111][1111];
    
    int minn(int x ,int y)
    {
       return x < y ? x : y;
    }
    
    int main ()
    {
       int n ,m ,i ,j;
       int ans ,x ,y;
       while(~scanf("%d %d" ,&n ,&m))
       {
          memset(map ,255 ,sizeof(map));
          memset(sum ,0 ,sizeof(sum));
          while(m--)
          {
             scanf("%d %d" ,&x ,&y);
             map[x][y] = 0;
          }
          for(ans = 0 ,i = 1 ;i <= n ;i ++)
          {
             for(j = 1 ;j <= n ;j ++)
             map[i][j] ? sum[j] ++ : sum[j] = 0;
             L[1] = 1;
             for(j = 2 ;j <= n ;j ++)
             {
                int k = j;
                while(k > 1 && sum[j] <= sum[k-1]) k = L[k-1];
                L[j] = k;
             }
             R[n] = n;
             for(j = n - 1 ;j >= 1 ;j --)
             {
                int k = j;
                while(k < n && sum[j] <= sum[k+1]) k = R[k+1];
                R[j] = k;
             }
             for(j = 1 ;j <= n ;j ++)
             {
                int now = minn(R[j] - L[j] + 1 ,sum[j]);
                if(ans < now) ans = now;
             }
          }
          printf("%d
    " ,ans);
       }
       return 0;
    }
    

  • 相关阅读:
    TCP/IP网络编程之优于select的epoll(一)
    TCP/IP网络编程之I/O流分离
    TCP/IP网络编程之套接字与标准I/O
    TCP/IP网络编程之多播与广播
    TCP/IP网络编程之多种I/O函数
    TCP/IP网络编程之I/O复用
    TCP/IP网络编程之进程间通信
    TCP/IP网络编程之多进程服务端(二)
    服务器被入侵了怎么办?
    sentos7为例添加python3和python2共存
  • 原文地址:https://www.cnblogs.com/csnd/p/12062941.html
Copyright © 2011-2022 走看看