zoukankan      html  css  js  c++  java
  • 洛谷P1565 牛宫

    题目描述

    AP 神牛准备给自己盖一座很华丽的宫殿。于是,他看中了一块N*M 的矩形空地。

    空地中每个格子都有自己的海拔高度。AP 想让他的宫殿的平均海拔在海平面之上(假设

    海平面的高度是0,平均数都会算吧?)。而且,AP 希望他的宫殿尽量大,能够容纳更

    多的人来膜拜他。请问AP 的宫殿最后会有多大?

    输入输出格式

    输入格式:

    第一行为N 和M。之后N 行,每行M 个数,描述的空地的海拔。

    输出格式:

    输出一行,表示宫殿最大面积。

    输入输出样例

    输入样例#1:
    3 2
    4 0
    -10 8
    -2 -2
    输出样例#1:
    4

    单调栈+dp

    O(n^2)枚举矩形左右范围,从上往下扫每一行,如果从1到k行的总和大于0,那么整块矩形可选;如果总和小于零,将其存入一个单调递减的单调栈,这样在之后的计算中,如果smm(1~k) - smm(1~x)>0,那么行x+1到行k这部分矩形可选。查询时候用二分查找比较快。

    万万没想到这题需要开long long,wa了一片

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 #define LL long long
     9 using namespace std;
    10 const int mxn=310;
    11 int read(){
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 int a[mxn][mxn];
    18 LL smm[mxn][mxn];
    19 int n,m;
    20 int ans=0;
    21 int f[mxn];
    22 LL st[mxn];
    23 int top=0;
    24 int find(LL x){
    25     int l=1,r=top,w=-1;
    26     while(l<=r){
    27         int mid=(l+r)>>1;
    28         if(st[mid]<x)r=mid-1,w=mid;
    29         else l=mid+1;
    30     }
    31     return w;
    32 }
    33 int main(){
    34     n=read();m=read();
    35     int i,j;
    36     for(i=1;i<=n;i++)
    37      for(j=1;j<=m;j++){
    38          a[i][j]=read();
    39          smm[i][j]=smm[i][j-1]+a[i][j];
    40      }
    41     st[0]=1e10;
    42     for(i=1;i<=m;i++)//左边界 
    43      for(j=i;j<=m;j++){//右边界
    44          LL tmp=0;
    45          top=0;
    46          for(int k=1;k<=n;k++){
    47             tmp+=smm[k][j]-smm[k][i-1];
    48             if(tmp>0)ans=max(ans,(j-i+1)*k);
    49             else{
    50                 int pos=find(tmp);
    51                 if(pos!=-1)
    52                     ans=max(ans,(k-f[pos])*(j-i+1));
    53             }
    54             if(tmp<st[top]){
    55                 st[++top]=tmp;
    56                 f[top]=k;
    57             }
    58          }
    59     }
    60     printf("%d
    ",ans);
    61     return 0;
    62 }
  • 相关阅读:
    数据库设计优化(一)--基础
    数据库设计--范式原则
    迭代器 与 foreach 的区别
    DBeaver中如何调整SQL编辑器的字体大小
    腾讯课堂下载回放视频
    超级美味的大盘鸡做法
    关闭或开启Win10系统的自动更新
    geoserver发布地图瓦片影像数据
    使用GeoServer发布Shapfile数据
    GeoServer下载与安装(Windows版)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6067295.html
Copyright © 2011-2022 走看看