算法实验T12——POJ1050 To the Max

题目链接

题目大意

求一个最大为 100*100 矩阵中的子矩阵中元素之和的最大值。

思路

        先考虑其一维的类似问题:最大连续子数组和问题,也就是在一个数组中找和最大的子数组,这个问题通常采用动态规划解决,状态转移方程式为DP[i] = max(DP[i-1]+a[i],a[i]),其中DP[i]表示以下标i结尾的最大连续子数组和,最终的答案是DP[0~n-1]中最大的一个。

        这道题其实可以很巧妙地往一维转化。如何将二维转化为一维?将二维的其中一维固定,即我们先定下子矩阵的宽,更具体地,选定子矩阵的宽是从L行到R行,那么就可以将这些行全部加成一行,对这一行求最大连续子数组。最终从所有选法中取最大即可。

AC代码

#include<iostream> 
#define INF 10000000
using std::cin;
using std::cout;

int DP(int M[][100], int l, int r, int n);
int main(){
	int n;
	int M[100][100];
	cin>>n;
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++){
			cin>>M[i][j];
		}
	}
	int ans = -INF, res;
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++){
			res = DP(M, i, j, n);
			if(ans < res) ans = res;
		}
	}
	cout<<ans;
	
	return 0;
}
int DP(int M[][100], int l, int r, int n){
	int d[100], dp[100];//dp[i]以i结尾的最大子段和 
	for(int i = 0; i < n; i++){
		d[i] = 0;
		for(int j = l ; j <= r; j++){
			d[i] += M[i][j];
		}
	}
	dp[0] = d[0];
	for(int i = 1; i < n; i++){
		dp[i] = (dp[i - 1] + d[i] > d[i] ? dp[i - 1] + d[i] : d[i]);
	}
	int res = -INF;
	for(int i = 0; i < n; i++){
		if(dp[i] > res){
			res = dp[i];
		}
	}
	return res;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值