• 51Nod 1051 最大子矩阵和


    题目

    一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值。

    例如:3*3的矩阵:

    -1 3 -1

    2 -1 3

    -3 1 2

    和最大的子矩阵是:

    3 -1

    -1 3

    1 2

     

    输入

    第1行:M和N,中间用空格隔开(2 <= M,N <= 500)。
    第2 - N + 1行:矩阵中的元素,每行M个数,中间用空格隔开。(-10^9 <= M[i] <= 10^9)

    输出

    输出和的最大值。如果所有数都是负数,就输出0。

    输入样例

    3 3
    -1 3 -1
    2 -1 3
    -3 1 2

    输出样例

    7

    分析

    最大子矩阵,类比一维最大子段和,复杂度n3

    代码

     1 /****************************
     2 User:Mandy.H.Y
     3 Language:c++
     4 Problem:51Nod
     5 Algorithm:DP
     6 Date:2018.8.15
     7 ****************************/
     8 //#include<bits/stdc++.h>
     9 #include<cstdio> 
    10 #include<iomanip> 
    11 #include<cmath> 
    12 
    13 using namespace std;
    14 
    15 const int maxn = 505;
    16 //数据范围-- 
    17 int m,n;
    18 long long ans;
    19 long long sum[maxn][maxn];
    20 long long t[maxn];
    21 
    22 char *TT,*mo,but[(1 << 15) + 2];
    23 #define getchar() ((TT == mo && (mo = ((TT = but) + fread(but,1,1 << 15,stdin)),TT == mo)) ? -1 : *TT++)
    24 template<class T>inline void read(T &x){
    25     x = 0;bool flag = 0;char ch = getchar();
    26     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
    27     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
    28     if(flag) x = -x;
    29 }
    30 
    31 template<class T>void putch(const T x){
    32     if(x > 9) putch(x / 10);
    33     putchar(x % 10 | 48);
    34 }
    35 
    36 template<class T>void put(const T x){
    37     if(x < 0) putchar('-'),putch(-x);
    38     else putch(x);
    39 }
    40 
    41 void file(){
    42     freopen("1051.in","r",stdin);
    43 //    freopen("1051.out","w",stdout);
    44 }
    45 
    46 void readdata(){
    47     read(m);read(n);
    48     for(int i = 1;i <= n; ++ i)
    49         for(int j = 1;j <= m; ++ j){
    50             long long x;read(x);
    51             sum[i][j] = sum[i - 1][j] + x;
    52             //只是竖向的一维前缀和,不是二维前缀和 
    53         }
    54 }
    55 
    56 void work(){
    57     ans = 0;
    58     //注意题目要求,全是负数输出0,初值赋成0 
    59     //(1LL << 61)记得是1LL,1默认为int 
    60     for(int i = 1;i <= n; ++ i)//枚举长的上界 
    61         for(int j = i;j <= n; ++ j){//枚举长的下界 
    62             for(int k = 1;k <= m; ++ k){
    63                 t[k] = sum[j][k] - sum[i - 1][k];
    64                 if(t[k - 1] > 0) t[k] += t[k - 1];//类比一维 
    65                 ans = max(ans,t[k]);
    66             }
    67         }
    68         
    69     put(ans);
    70 }
    71 
    72 int main(){
    73 //    file();
    74     readdata();
    75     work();
    76     return 0;
    77 }
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    缓存IO读写的方式
    mapboxgl 纠偏百度地图
    GIS常用算法
    DevExpress VCL TdxBar工具栏上的按钮等居右对齐无效的问题
    dxRichEditControl、Invalid operation in GDI+ (Code: 2)
    Indy+POP/SMTP收发邮件
    VUE父组件给子组件传对象
    Linux下进程间通信
    Linux下守护进程
    Linux下进程控制相关
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11360651.html
Copyright © 2020-2023  润新知