【HDU1081】最大子矩阵的和

1.题目链接。题目的大意就是给定一个矩阵,求出这个矩阵中的一个和最大的子矩阵。

2.emmm,显然DP。我们肯定都写过HDU1003那个最大连续的子段和。这个题的解法其实差不多一个意思。我们可以把行压缩掉,怎么压缩?这样压缩:我们只考虑列dp[k]就是前k列的最大子矩阵的和。那么行我们这样处理:把每一行加起来压缩成一个数据。举例说明,比如我们有一个10*10的矩阵,我们首先考虑1*10,也就是1行10列的矩阵,记下最大值max,然后考虑2*10.这个怎么办呢?我们把每一列加起来作为一个数据,那么最后还是转化成了求1*10的。其他的都是这样操作,那么把二维其实就转化成了一维。所以我们需要预处理数据,就是知道任意的前k列第i行到第j行的和,这个在输入的时候直接用数据保存一下。这样我们转移的时候其实就是这样的:我们考虑前k的列中和最大的子矩阵,其实他是可以从k-1列转移过来。怎么转移取决于我们取多少行。如果是dp[k-1]>0,我们就枚举所有的组合去到最大,如果如果没有贡献,我们就取当前第i行到第j行的矩阵。emmm,还是看代码吧,我写的应该还是挺容易明白的。

#include<bits/stdc++.h>
using namespace std;
int t[101][101], dp[101];
#pragma warning(disable:4996)
int main() {
	int n;
	while (scanf("%d", &n) != EOF && n != 0)
	{
		int  ans = -0xFFFFFFF, tmp;
		memset(t, 0, sizeof(t));
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= n; j++)
			{
				scanf("%d", &tmp);
				t[j][i] = t[j][i - 1] + tmp;//预处理一下数据
			}
		}
		for (int i = 0; i <= n - 1; i++) {
			for (int j = i + 1; j <= n; j++) {
				memset(dp, 0, sizeof(dp));
				for (int k = 1; k <= n; k++)
				{
					dp[k] = max(dp[k - 1] + t[k][j] - t[k][i], t[k][j] - t[k][i]);
					ans = max(ans, dp[k]);
				}
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值