【RQNOJ PID106】最大加权矩形(DP)

题目描述

给定一个正整数n( n<=100),然后输入一个N*N矩阵。求矩阵中最大加权矩形,即矩阵的每一个元素都有一权值,权值定义在整数集上。从中找一矩形,矩形大小无限制,是其中包含的所有元素的和最大 。矩阵的每个元素属于[-127,127]
例:
0 –2 –7 0 在左下角: 9 2
9 2 –6 2 -4 1
-4 1 –4 1 -1 8
-1 8 0 –2 和为15

输入格式

第一行:n,接下来是n行n列的矩阵。

输出格式

最大矩形(子矩阵)的和。

输入

4
0 –2 –7 0
9 2 –6 2
-4 1 –4 1
–1 8 0 –2

输出

15

题解

设mat[i][j]为第i列第0行到第j行的和,这样,枚举选择矩形第x行到第y行,就形成了一维数组,形如:
( mat[i][y]-mat[i][x-1] ) , ( mat[i+1][y]-mat[i+1][x-1] ) ,( mat[i+2][y]-mat[i+2][x-1] ),( mat[i+3][y]-mat[i+3][x-1] )..........................
这样就是经典的最大字段和问题了。

参考代码

#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1000000000
#define mod 1000000007
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }
    return x*f;
}
void Out(int a) {
    if(a<0) putchar('-'),a=-a;
    if(a>=10) Out(a/10);
    putchar(a%10+'0');
}

const int N=105;
int mat[N][N];
int main()
{
    int n=read(),ans=-inf,x;
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
            x=read(),mat[i][j]=mat[i][j-1]+x;
    for(int i=1;i<=n;i++){
       for(int j=i;j<=n;j++){
          	  int sum=0;
          	  for(int k=1;k<=n;k++)
              {
           	     if(sum>0) sum+=mat[k][j]-mat[k][i-1];
           	     else sum=mat[k][j]-mat[k][i-1];
           	     ans=max(sum,ans);
              }
          }
    }
    Out(ans);
    puts("");
    return 0;
}

posted @ 2017-07-11 16:08  江南何采莲  阅读(233)  评论(0编辑  收藏  举报