您的位置:首页 > 其它

UVa108 UVa10827 最大连续子矩阵和

2016-09-09 16:02 417 查看
UVa 108

题意:

求最大连续子矩阵和

分析:

类似于一维求前缀和一样,用sum[i][j]求一下以(i,j)为右下角端点的矩形的和,然后枚举矩阵的y轴的上下边界,然后扫一遍x轴,找到最小的前缀子矩形,然后当前矩形和sum[i][k] - sum[j][k]减去最小的就是最大的。

const int N = 100 + 9;
int a

, sum

, r
, n;
int main() {
//freopen("f.txt","r",stdin);
while (~scanf ("%d", &n) ) {

memset (sum, 0, sizeof (sum) );
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
scanf ("%d", &a[i][j]);
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];
}
int ans = -INF;
for (int i = 1; i <= n; i++) //上边界
for (int j = 0; j < i; j++) { //下边界
int minn = 0;
for (int k = 1; k <= n; k++) {
int t = sum[i][k] - sum[j][k] - minn;
if (t > ans) ans = t;
if (minn > sum[i][k] - sum[j][k]) minn = sum[i][k] - sum[j][k];
}
}
printf ("%d\n", ans);
}
return 0;
}


UVa10827

题意:

求环面上最大连续子矩阵和

分析:

这题是上题的进阶版,因为给出的矩阵是球形的,所以不难想到倍增什么的,所以每一行增加一倍,每一列也增加一倍,构成2N*2N的矩阵,然后我们只要求一下最大边长是N的最大连续子矩阵就好了。

因为最大边长是N,所以我们枚举左上角坐标和矩形的长宽,然后维护最大子矩阵和即可。

const int N = 75 * 2 + 9;
int a

, sum
, r
, n;
int main() {
//freopen("f.txt","r",stdin);
int T;
scanf ("%d", &T);
while (T--) {
scanf ("%d", &n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
scanf ("%d", &a[i][j]);
a[i][j + n] = a[i + n][j] = a[i + n][j + n] = a[i][j]; //扩展矩阵
}
int ans = -INF;
for (int i = 0; i < n; i++) //左上角横坐标
for (int j = 0; j < n; j++) //纵坐标
for (int l = 0; l < n; l++) //长(列)
for (int w = 0; w < n; w++) { //宽(行)
r[w] = a[i + l][j + w]; //第w行的和
if (w) r[w] += r[w - 1];
if (l) sum[w] += r[w];
else sum[w] = r[w];
if (ans < sum[w]) ans = sum[w];
}
printf ("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: