• uva 10755 Garbage Heap


    https://vjudge.net/problem/UVA-10755

    题意:

    给出一个长方体,叫你求哪个子矩阵的和最大,输出的是最大值。

    思路:

    首先,n的规模是20,那么最常规的算法,枚举起点,枚举终点,之后循环计算,那么这个的复杂度就是O(N^9)。

    这个想法其实是比较自然的,那么可以加一些优化进去,减小复杂度。

    首先,三维的问题,可以通过降维解决,枚举竖坐标,降成一维解决。

    降成一维之后,如果还是枚举起点与终点,那么复杂度还是高达O(N^8)。

    那么其实坐标平面的问题可以用前缀和来优化,所以再用上前缀和优化。

    之后,最大子矩阵就可以用动态规划解决了。

    tmp = sum[i][j] - sum[k-1][j],这里的sum记录的是降维之后的前缀和,然后k从1到x枚举,i从k到x枚举,j从1到y枚举,

    这个操作把一个矩阵变成了一条线,于是就用最大连续和的思想解决。

    总的复杂度是O(N^5)。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 long long a[25][25][25];
     7 
     8 long long b[25][25];
     9 long long sum[25][25];
    10 
    11 int main()
    12 {
    13     int t;
    14 
    15     scanf("%d",&t);
    16 
    17     while (t--)
    18     {
    19         long long ans = -1e18;
    20 
    21         int x,y,z;
    22 
    23         scanf("%d%d%d",&x,&y,&z);
    24 
    25         for (int i = 1;i <= x;i++)
    26             for (int j = 1;j <= y;j++)
    27             for (int k = 1;k <= z;k++)
    28             scanf("%lld",&a[i][j][k]);
    29 
    30         for (int i = 1;i <= z;i++)
    31             for (int j = i;j <= z;j++)
    32         {
    33             memset(b,0,sizeof(b));
    34 
    35             for (int k = i;k <= j;k++)
    36             {
    37                 for (int m = 1;m <= x;m++)
    38                     for (int n = 1;n <= y;n++)
    39                     b[m][n] += a[m][n][k];
    40             }
    41 
    42             memset(sum,0,sizeof(sum));
    43 
    44             for (int m = 1;m <= x;m++)
    45                 for (int n = 1;n <= y;n++)
    46             {
    47                 sum[m][n] = sum[m-1][n] + sum[m][n-1] - sum[m-1][n-1] + b[m][n];
    48             }
    49 
    50             for (int m = 1;m <= x;m++)
    51                 for (int n = m;n <= x;n++)
    52             {
    53                 long long orz = 0;
    54 
    55                 for (int k = 1;k <= y;k++)
    56                 {
    57                     long long tmp = sum[n][k] - sum[m-1][k];
    58 
    59                     ans = max(ans,tmp - orz);
    60 
    61                     orz = min(tmp,orz);
    62                 }
    63             }
    64         }
    65 
    66         printf("%lld
    ",ans);
    67 
    68         if (t) printf("
    ");
    69     }
    70 
    71     return 0;
    72 }
  • 相关阅读:
    SpringMVC + MyBatis简单示例
    JSP---JSTL核心标签库的使用
    HBASE安装 (HA)
    HBase 常用Shell命令(转载)
    kafka quick start
    在IDEA中实战Git
    kibana6.2.2安装
    elasticsearch-head插件安装
    elasticsearch6.2.2安装
    jdk1.8安装
  • 原文地址:https://www.cnblogs.com/kickit/p/7650808.html
Copyright © 2020-2023  润新知