• [OIBH] 糖果盒(Candy Box)——又一个最大子矩形


    http://codewaysky.sinaapp.com/problem.php?id=1056

    这题和奶牛浴场略有区别,奶牛浴场只需要求出最大子矩形,而这题要求的是最大权重子矩形,不一定要最大的面积,但要最大的权重和

    思路是先求出每个最大子矩形,然后求出每个矩形的左上点和右下点,然后用二维数转数组进行求和,保存最优解

    View Code
      1 #include<iostream>
      2 #include<string>
      3 #include<algorithm>
      4 #include<stdio.h>
      5 #include<memory.h>
      6 using namespace std;
      7 
      8 int sum[1010][1010];
      9 int v[1010][1010];
     10 int l[1010],r[1010],h[1010];
     11 int n,m;
     12 
     13 //****************************//树状数组
     14 int lowbit(int x)
     15 {
     16     return x&-x;
     17 }
     18 
     19 void add(int x,int y,int w)
     20 {
     21     int i,j;
     22     for(i=x;i<=n;i+=lowbit(i))
     23     {
     24         for(j=y;j<=m;j+=lowbit(j))
     25             sum[i][j]+=w;
     26     }
     27 }
     28 
     29 int get_sum(int x,int y)
     30 {
     31     int i,j,ans=0;
     32     for(i=x;i>0;i-=lowbit(i))
     33     {
     34         for(j=y;j>0;j-=lowbit(j))
     35         {
     36             ans+=sum[i][j];
     37         }
     38     }
     39     return ans;
     40 }
     41 //*****************************//
     42 
     43 int find(int x1,int y1,int x2,int y2)
     44 {
     45     return get_sum(x2,y2)-get_sum(x1-1,y2)-get_sum(x2,y1-1)+get_sum(x1-1,y1-1);
     46 }
     47 
     48 int main()
     49 {
     50     int i,j,w,x1,x2,y1,y2;
     51     freopen("D:\\in.txt","r",stdin);
     52     while(scanf("%d%d",&n,&m)==2)
     53     {
     54         memset(sum,0,sizeof(sum));
     55         memset(v,0,sizeof(v));
     56         for(i=1;i<=n;i++)
     57         {
     58             for(j=1;j<=m;j++)
     59             {
     60                 scanf("%d",&w);
     61                 if(!w)
     62                     v[i][j]=1;
     63                 else
     64                     add(i,j,w);
     65             }
     66         }
     67         for(i=0;i<=m;i++)
     68         {
     69             h[i]=0;l[i]=1;r[i]=m;
     70         }
     71         int lm,rm,ans=0,temp;
     72         for(i=1;i<=n;i++)
     73         {
     74             lm=1;
     75             for(j=1;j<=m;j++)
     76             {
     77                 if(!v[i][j])
     78                 {
     79                     h[j]++;
     80                     if(lm>l[j])
     81                         l[j]=lm;
     82                 }
     83                 else
     84                 {
     85                     h[j]=0; //边界不能有洞,所以障碍点高度是0,而不是1
     86                     l[j]=1;
     87                     r[j]=m;
     88                     lm=j+1; //由于边界不能有洞,所以加1
     89                 }
     90             }
     91             rm=m;
     92             for(j=m;j>0;j--)
     93             {
     94                 if(r[j]>rm)
     95                     r[j]=rm;
     96                 if(h[j])
     97                 {
     98                     y1=l[j];y2=r[j]; //处理出举行的左上点和右下点
     99                     x1=i-h[j]+1;x2=i;
    100                     temp=find(x1,y1,x2,y2);  //利用二维数转数组进行求和
    101                     if(temp>ans)
    102                         ans=temp;
    103                 }
    104                 else
    105                     rm=j-1; //同理减一
    106             }
    107         }
    108         printf("%d\n",ans);
    109     }
    110     return 0;
    111 }
  • 相关阅读:
    springboot-项目属性配置
    网络编程
    HttpServlet---getLastModified与缓存
    TCP的三次握手和四次挥手
    数据库事务隔离级别-- 脏读、幻读、不可重复读
    js 数组,字符串,json互相转换
    表格单元格td设置宽度无效的解决办法
    判断IE版本的HTML语句详解,如:<!--[if IE 9]> 仅IE9可识别 <![endif]-->
    IE主页被篡改为360导航终极处理办法
    前端常见问题
  • 原文地址:https://www.cnblogs.com/ka200812/p/2709217.html
Copyright © 2020-2023  润新知