题目:http://acm.hdu.edu.cn/showproblem.php?pid=1081
自己真够垃圾的,明明做过一维的这种题,但遇到二维的这种题目,竟然不会了,我也是服了(ps:猪啊)。
最终还是看了题解。
代码如下:
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #define inf 0x3f3f3f3f using namespace std; int n,w[110][110],t; int main() { while(scanf("%d",&n)!=EOF) { memset(w,0,sizeof(w)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&t); w[i][j]+=w[i][j-1]+t; } } int maxx=-inf; for(int i=1;i<=n;i++) { for(int j=i;j<=n;j++) { int sum=0; for(int k=1;k<=n;k++) { if(sum<0) sum=0; sum+=w[k][j]-w[k][i-1]; if(sum>maxx) maxx=sum; } } } printf("%d\n",maxx); } return 0; }
大神的题解:
这一题就是将一维的最大字段和扩展到二维,在一维的求最大字段和的过程中是这样操作的:
int max_sum(int n) { int i, j, sum = 0, max = -10000; for(i = 1; i <= n; i++) { if(sum < 0) sum = 0; sum += a[i]; if(sum > max) max = sum; } return sum; }
扩展到二维的时候也是同样的方法,不过需要将二维压缩成一维,所以我们要将数据做一下处理,使得map[i][j]从表示第i行第j个元素变成表示第i行前j个元素和,这样map[k][j]-map[k][i]就可以表示第k行从i->j列的元素和。只要比一维多两层循环枚举i和j就行了。
#include <iostream> #define MAX 101 using namespace std; int map[MAX][MAX]; int main() { int n, i, j, temp, k; while(scanf("%d", &n) != EOF) { memset(map, 0, sizeof(map)); for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) { scanf("%d", &temp); map[i][j] += map[i][j - 1] + temp;//这里表示第i行的前j列之和 } int max = -100000; for(i = 1; i <= n; i++) for(j = i; j <= n; j++) { int sum = 0; for(k = 1; k <= n; k++) { if(sum < 0) sum = 0; sum += map[k][j] - map[k][i - 1];//这里表示前k行,i->j列之和 if(sum > max) max = sum; } } printf("%d\n", max); } return 0; }
时间: 2024-10-06 00:54:11