Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 36968 | Accepted: 19480 |
Description
Input
Output
Sample Input
4 0 -2 -7 0
9 2 -6 2 -4 1 -4 1
-1 8 0 -2
Sample Output
15
Source
/*********************************************************** B Accepted 192 KB 16 ms C++ 1113 B 题意:求最大的连续的矩阵和 算法:dp 推荐先做:HDU 1003 Max Sum 求最大的连续和 思路:开始先做了 hdu 1003, 后来又看了别人的这题的思路才知道的了 先解决每一行的最大连续和问题:(也就相当于 hdu 1003 了) 数字:a[0]----a[n-1] 状态转移方程:dp[0] = a[0] dp[i] = max(dp[i-1], 0)+a[i] 最后遍历 dp[] 找出最大的 dp[i] 就是这一行数的最大连续和 状态转移方程样例分析: a[]: 6 -1 3 -10 8 7 dp[]:6 5 8 0 8 15 那么对于这一题: 只要依次按照行来枚举,把要求的矩阵压缩成一行【相加】,再套用上面的做法就好了 对于第一行: 求出第一行的最大连续和, 更新最大值 把第二行的数加到第一行, 求第一行最大连续和, 更新最大值 把第三行的数加到第一行, 求最大连续和,更新 Max 。 。 。 第 N 行的数加到第一行。。。 此时只是第一行的数组改变了,下面的不变 对于第二行:求出第二行的最大连续和, 更新最大值 把第三行的数加到第二行, 求出第二行的最大连续和, 更新最值 。 。 。 把第 N 行的数加到第二行,求第二行的最大连续和, 更新最值 。。。 对于第N行: 求第N行的最大连续和,更新 Max **************************************************************************/ #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; const int maxn = 110; int a[maxn][maxn]; int dp[maxn]; int Max_sum(int a[], int n) //求出数组 a[] 的最大连续和 { dp[0] = a[0]; for(int i = 1; i < n; i++) dp[i] = max(dp[i-1], 0) + a[i]; int Max = dp[0]; for(int i = 1; i < n; i++) Max = max(Max, dp[i]); return Max; } int main() { int n; while(scanf("%d", &n) != EOF) { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) scanf("%d", &a[i][j]); int Max = 0; for(int i = 0; i < n; i++) //遍历每一行 { int m = Max_sum(a[i], n); Max = max(Max, m); for(int j = i+1; j < n; j++) //把第 j 行的数加到第 i 行,再求最大矩阵和【i, i+1,...j】 { for(int k = 0; k < n; k++) { a[i][k] += a[j][k]; //改变的是第 i 行,不会影响后面的结果 } m = Max_sum(a[i], n); Max = max(Max, m); } } printf("%d\n", Max); } return 0; } /* 4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 */