zoukankan      html  css  js  c++  java
  • Luogu_1565_牛宫_(最大子矩阵)

    描述


     

    http://www.luogu.org/problem/show?pid=1565

    给出一个n*m的矩阵,求最大的且和值为正的子矩阵.

    分析


    很容易想到的是用前缀和维护,暴力枚举左上角和右下角,这样的复杂度是O(n^4)的.(虽然洛谷上这道题也能过)

    一种神奇的方法:用前缀和记录每一行的前缀和.枚举的时候先枚举左右端点,然后分别算出左右端点之间每一行的和值,把一行看作一个单元(将一行压缩成一个点),求以行为单元的前缀和.然后前缀和相减可以得到子矩阵.而题目要求子矩阵的和值要为正,所以必须是值大的前缀和减值小的(相等不能减),所以把前缀和排个序.对于子矩阵t[i]-t[j](t是前缀和),t[i]必须大于t[j],而且t[i]代表的前缀和要尽可能"靠下",这样子矩阵才能尽可能大.所以我们排序后扫一遍前缀和,记录当前前缀和t[i]之前的(比t[i]大的)前缀和中最靠下的位置down,然后用down-t[i].id表示两个前缀和之差代表的子矩阵的高度(可能为负),记录最大高度h,最后乘以底边的长度(j-i+1)即可.

    注意:

    1.前缀和要加上0.

    2.相同的不能相减,所以相同的前缀和把序号小的放在上面,这样减出来的就是负的.

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 
     5 const int maxn=200+5;
     6 int n,m;
     7 ll ans;
     8 ll s[maxn][maxn];
     9 
    10 struct node{
    11     ll x,id;
    12     node(){}
    13     node(ll x,ll id):x(x),id(id){}
    14 }t[maxn];
    15 bool cmp(node x,node y){ 
    16     if(x.x==y.x) return x.id<y.id;
    17     return x.x>y.x; 
    18 }
    19 void solve(){
    20     for(int i=1;i<=m;i++)
    21         for(int j=i;j<=m;j++){
    22             for(int k=1;k<=n;k++) t[k]=node(t[k-1].x+s[k][j]-s[k][i-1],k);
    23             t[0]=node(0,0);
    24             sort(t,t+n+1,cmp);
    25             ll down=t[0].id,h=0;
    26             for(int k=0;k<=n;k++){
    27                 h=max(h,down-t[k].id);
    28                 down=max(down,t[k].id);
    29             }
    30             ans=max(ans,h*(j-i+1));
    31         }
    32     printf("%lld
    ",ans);
    33 }
    34 void init(){
    35     scanf("%d%d",&n,&m);
    36     for(int i=1;i<=n;i++)
    37         for(int j=1;j<=m;j++){
    38             int t; scanf("%d",&t);
    39             s[i][j]=s[i][j-1]+t;
    40         }
    41 }
    42 int main(){
    43     init();
    44     solve();
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    oracle11g expdp/impdp数据库
    SqlServer触发器
    tomcat8.5.20配置https
    oracle常用函数积累
    Eclipse 搭建tomcat+动态项目完整版
    Windows7下ftp服务器
    Orcle定时生成表数据作业
    Oracle将一列值逗号拼接wm_concat函数
    Oracle表空间 ORA-01653:
    node+mongodb+ionic+cordova
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5528204.html
Copyright © 2011-2022 走看看