• NYOJ-104最大和


    我看了好多博客,都是拿一维的做基础,一维的比较简单,所以要把二维的化成一维的,一维的题目大意:给了一个序列,求那个子序列的和最大,这时候就可以用dp来做,首先dp[i]表示第i个数能构成的最大子序列和,所以dp[i] = dp[i - 1] > 0 ? dp[i - 1] + dp[i] : dp[i]; 这个比较好理解,但是二维的,貌似想不起来这样写了。但是,如果转换一下,还是可以的,方法如下:

    1. 将行划分,划分的结果为所有情况

    2.将划分好的“新行”进行合并成“一行”,

    3.对“一行”进行一维的求最大子段和

    举个例子:

    0  -2  -7  0

    9   2  -6  2

    -4  1  -4   7

    -1  8  0   -2

    我们分别用i j表示起始行和终止行,遍历所有的可能:

    for(i=1;i<=n;i++)

    for(j=i;j<=n;j++) {}

    我们考察其中一种情况 i=2 j=4,这样就相当与选中了2 3 4三行,求那几列的组合能获得最大值,由于总是 2 3 4行,所以我们可以将这3行”捆绑”起来,变为求 4(9-4-1),11(8+2+1),-10(-6-4+0),7(7+2-2)的最大子段和,ok,问题成功转化为一维的情况!

    注意:代码中还有一个地方需要注意,就是读入原始数据的时候,要处理一下,再保存到数组中,每一行的数据都不是原来的数据,而是加上同一列以上各行的数据,这样以来,在合并求和的时候就比较方便了。比如求2,3两行的和,只要第三行的值减去第一行的值就行了

    代码如下:

     1 #include<iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define inf 99999999
     6 using namespace std;
     7 const int n = 105;
     8 int map[n][n];
     9 int temp[n];
    10 int ans;
    11 //一维序列求最大和
    12 int find_max(int a[], int m)
    13 {
    14     int max_sum = -inf;
    15     int res = 0;
    16     for (int k = 1; k <= m; k++)
    17     {
    18         if (res > 0)
    19             res += a[k];
    20         else
    21             res = a[k];
    22         if (res > max_sum)
    23             max_sum = res;
    24     }
    25     return max_sum;
    26 }
    27 int main()
    28 {
    29     int n;
    30     cin >> n;
    31     while (n--)
    32     {
    33         memset(map, 0, sizeof(map));
    34         int r, c;
    35         int t;
    36         cin >> r >> c;
    37         for (int i = 1; i <= r; i++)
    38         {
    39             for (int j = 1; j <= c; j++)
    40             {
    41                 cin >> map[i][j];
    42                 map[i][j] += map[i - 1][j];//处理一下
    43             }
    44         }
    45         ans = -inf;
    46         for (int i = 0; i < r; i++)
    47         {
    48             for (int j = i + 1; j <= r; j++)//枚举所有情况
    49             {
    50                 for (int k = 1; k <= c; k++)//将“新和”计算出来保存到数组temp中
    51                 {
    52                     temp[k] = map[j][k] - map[i][k];
    53                 }
    54                 //找到这段当中的最大和
    55                 t = find_max(temp, c);
    56                 if (t > ans)
    57                     ans = t;//ans全局变量保存结果,即最大值
    58             }
    59         }
    60         cout << ans << endl;
    61     }
    62 
    63     return 0;
    64 }
  • 相关阅读:
    使用sorted函数对字典元素排序
    PAT (Basic)1004 成绩排名 (Python实现)
    Python中的a+=b和a=a+b之间的区别是什么?
    Shell while循环用法总结
    PAT (Basic)1027 打印沙漏 (Python实现)
    python 基础应用2
    python 基础知识1
    python 基础知识2-数据类型
    python 基础应用1
    PHP提高SESSION响应速度的方法
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4171946.html
Copyright © 2020-2023  润新知