洛谷P1719最大加权矩形

我们维护一个前缀和sum[i][j]表示从左上角到i,j这个点的覆盖的矩形的权值和,怎么求呢?我们画张图

我们现在要求右下角sum[i][j],发现将这个点刨出去,能得到两个有重叠部分的矩形sum[i-1]s[j]和sum[i][j-1],重合部分为sum[i-1][j-1]那么因为我们求和是一个递推的过程,所以这几块都已经被处理完了,那么我们就可以得到sum[i][j]=a[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1],这样前缀和就求完了,实际上我们求解最大矩阵的过程不完全是dp,我们枚举矩形的左上和右下端点,这样我们就确定了一个矩形,那么矩形和如何得到呢?和刚刚求前缀和类似,我们再来张图

假如我们要求的是右下黑框的面积,整张图是红框,发现我们要求的可以由大矩形减去左侧矩形再减去上面矩形得到,然后我们又发现左上绿框的面积被减了两次,所以我们要加回来,那么很轻松的就可以得到S(i,j,k,e)表示左上坐标为(i,j)右下坐标为(k,e)那么S(i,j,k,e)=S(1,1,k,e)-S(k,j-1)(左侧矩形)-S(i-1,k)(上面矩形)+S(i-1,j-1)(左上小矩形)然后取max就好

代码

//By AcerMo 
#include<iostream>
using namespace std;
int n,a[150][150],sum[150][150];
signed main()
{
	cin>>n;int ans=0;
	for (int i=1;i<=n;i++)
	for (int k=1;k<=n;k++)
	cin>>a[i][k];
	for (int i=1;i<=n;i++)
		for (int k=1;k<=n;k++)
			sum[i][k]=a[i][k]+sum[i][k-1]+sum[i-1][k]-sum[i-1][k-1];
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			for (int k=i;k<=n;k++)
				for (int e=j;e<=n;e++)
					ans=max(ans,sum[k][e]-sum[i-1][e]-sum[k][j-1]+sum[i-1][j-1]);
	cout<<ans;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/acerandaker/article/details/81120986
今日推荐