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 }
原文地址:https://www.cnblogs.com/Howe-Young/p/4171946.html