zoukankan      html  css  js  c++  java
  • POJ 1050 To the Max

    To the Max
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 36422   Accepted: 19130

    Description

    Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle.  As an example, the maximal sub-rectangle of the array: 
    0 -2 -7 0  9 2 -6 2  -4 1 -4 1  -1 8 0 -2  is in the lower left corner: 
    9 2  -4 1  -1 8  and has a sum of 15. 

    Input

    The input consists of an N * N array of integers. The input begins with a single positive integer N on a line by itself, indicating the size of the square two-dimensional array. This is followed by N^2 integers separated by whitespace (spaces and newlines). These are the N^2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in the second row, left to right, etc. N may be as large as 100. The numbers in the array will be in the range [-127,127].

    Output

    Output the sum of the maximal sub-rectangle.

    Sample Input

    4
    0 -2 -7 0 9 2 -6 2
    -4 1 -4  1 -1
    
    8  0 -2

    Sample Output

    15

    传说中经典的DP问题,昨天比赛时为了解一道看起来类似的题直接网搜了此题的结题报告,发现暴力转化为一维数组求最长子序列的思想果然高明(可是比赛那道题还是TLE了T^T)
    二维数组转化以为数组举例:
    0 -2 -7 0
    9 2 -6 2
    可以转化为:
    9 0 -13 2
    也就是把纵向的一列求和,然后再求最大子序列和即为这个最大子矩阵的和

    求最大子序列和用了一点DP思想,DP之前也没怎么写过,每次想DP总想着区间,这里的DP是用点来做的
    用一个数组f[i]代表数组s中以s[i]结尾的最大子序列的和,这样得到了状态转移方程:
    f[i]=f[i-1]+f[i]>f[i]?f[i-1]+f[i]:f[i];

    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 
     7 long g[101][101];
     8 long s[101];
     9 long f[101];
    10 
    11 long FindMax(int n)
    12 {
    13     memset(f,0,sizeof(f));
    14     for(int i=1;i<=n;i++)
    15         f[i]=(f[i-1]+s[i]>s[i]?f[i-1]+s[i]:s[i]);
    16     long maxn=f[1];
    17     for(int i=2;i<=n;i++)
    18         if(f[i]>maxn)
    19             maxn=f[i];
    20     return maxn;
    21 }
    22 
    23 int main()
    24 {
    25     int n;
    26     long ans,result;
    27 
    28     while(scanf("%d",&n)==1)
    29     {
    30         for(int i=1;i<=n;i++)
    31             for(int j=1;j<=n;j++)
    32                 scanf("%ld",&g[i][j]);
    33         for(int len=1;len<=n;len++)
    34         {
    35             for(int y=1;y<=n-len+1;y++)
    36             {
    37                 for(int x=1;x<=n;x++)
    38                     s[x]=0;
    39                 for(int x=1;x<=n;x++)
    40                     for(int t=y;t<y+len;t++)
    41                         s[x]+=g[x][t];
    42                 result=FindMax(n);
    43                 if(len==1&&y==1)
    44                     ans=result;
    45                 else
    46                     if(ans<result)
    47                         ans=result;
    48             }
    49         }
    50         printf("%ld
    ",ans);
    51     }
    52 
    53     return 0;
    54 }
    [C++]
  • 相关阅读:
    算法
    用python代码编写象棋界面,棋盘覆盖问题
    深浅拷贝的原理
    MongoDB简介,安装,增删改查
    DBUtils-Python数据库连接池
    websocket
    Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
    跨域
    最长公共子序列/子串 LCS(模板)
    寒假作业---蓝桥杯---DFS
  • 原文地址:https://www.cnblogs.com/lzj-0218/p/3185898.html
Copyright © 2011-2022 走看看