您的位置:首页 > 其它

HDU 1559 最大子矩阵

2017-03-22 18:10 211 查看

题面

给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大。

Input

输入数据的第一行为一个正整数T,表示有T组测试数据。每一组测试数据的第一行为四个正整数m,n,x,y(0 < m,n <1000 AND 0 < x <= m AND 0 < y <= n),表示给定的矩形有m行n列。接下来这个矩阵,有m行,每行有n个不大于1000的正整数。

Output

对于每组数据,输出一个整数,表示子矩阵的最大和。

Sample Input

1

4 5 2 2

3 361 649 676 588

992 762 156 993 169

662 34 638 89 543

525 165 254 809 280

Sample Output

2474

大致思路

用一个二维数组进行保存对应的状态。

dp[i][j]代表从(0,0)点到(i,j)点的数字和,所以可以得到状态转移方程:

dp[i][j]+=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]

然后考虑最大矩阵和的情况。满足要求的最大的前提是i,j分别大于x,y。然后另外声明一个变量保存最大值,并分别与每一种情况进行比较。

当i,j都满足条件时,以(i,j)为右下角的矩阵值为:dp[i][j]-dp[i-x][j]-dp[i][j-y]+dp[i-x][j-y]

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int dp[1010][1010];
int main()
{
int T;
cin>>T;
while(T--)
{
memset(dp,0,sizeof(dp));
int m,n,x,y,Max=-1000;
cin>>m>>n>>x>>y;
for(int i=1;i<=m;++i)
for(int j=1;j<=n;++j){
cin>>dp[i][j];
dp[i][j]+=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
if(i>=x&&j>=y)
Max=max(Max,dp[i][j]-dp[i-x][j]-dp[i][j-y]+dp[i-x][j-y]);
}
cout<<Max<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp