E: Maximum Sum Background A problem that is simple to solve in one dimension is often much more difficult to solve in more than one dimension. Consider satisfying a boolean expression in conjunctive normal form in which each conjunct consists of exactly 3 disjuncts. This problem (3-SAT) is NP-complete. The problem 2-SAT is solved quite efficiently, however. In contrast, some problems belong to the same complexity class regardless of the dimensionality of the problem. The Problem Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the largest sum. 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. A sub-rectangle is any contiguous sub-array of size or greater located within the whole array. As an example, the maximal sub-rectangle of the array: is in the lower-left-hand corner: and has the sum of 15. Input and Output The input consists of an 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 integers separated by white-space (newlines and spaces). These integers make up the array in row-major order (i.e., all numbers on the first row, left-to-right, then all numbers on 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]. The output is 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 这个最大子矩阵的题目,其实是最长子序列的扩展。 基本思想:分类,子矩阵可能是1~n行的,对每一种情况分别施加累加操作,将结果保存为一个数组,然后最长子序列做。 #include<stdio.h> #include<stdlib.h> int N; #define MAX_N 101 int matrix[MAX_N][MAX_N]; int sum[MAX_N]; void initial_sum() { for(int i=0;i<N;i++) { sum[i]=0; } } void set() { scanf("%d",&N); for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { scanf("%d",&matrix[i][j]); } } } int solve() { int cur_sum=0; int result=0; for(int i=0;i<N;i++)//从第i行开始往下扫描 { initial_sum(); for(int j=i;j<N;j++)//开始遍历从i到N-1行 { cur_sum=0; for(int k=0;k<N;k++) { sum[k]+=matrix[j][k]; if(cur_sum>=0) { cur_sum+=sum[k]; } else { cur_sum=sum[k]; } result=result>cur_sum?result:cur_sum; } } } return result; } int main (void) { set(); printf("%d",solve()); }
10-13