题解 P1719 【最大加权矩形】
Yanzy2333
·
·
题解
题外话:
n久没有写题解了,咕值掉的不爱掉了,赶紧写一个题解加一下QωQ
正文:
这道题其实还是满水的。
首先呢。。。
你要算一个矩阵的内部元素和,比如说下图中的红色部分:
\ \ \ 0\ -2\ -7\ \ \ \ \ \ \ 0
\ \ \ 9\ \ \ \ \ \ \color{red}2\ -6\ \ \ \ \ \ \ \color{black}2
-4\ \ \ \ \ \ \color{red}1\ -4\ \ \ \ \ \ \ \color{black}1
-1\ \ \ \ \ \ 8\ \ \ \ \ \ 0\ \ -2
其实可以等同于蓝色部分:
\color{blue}\ \ \ 0\ -2\ -7\ \ \ \ \ \ \ \color{black}0
\color{blue}\ \ \ 9\ \ \ \ \ \ 2\ -6\ \ \ \ \ \ \ \color{black}2
\color{blue}-4\ \ \ \ \ \ 1\ -4\ \ \ \ \ \ \ \color{black}1
-1\ \ \ \ \ \ 8\ \ \ \ \ \ 0\ \ -2
减去绿色部分
\color{green}\ \ \ 0\ -2\ -7\ \ \ \ \ \ \ \color{black}0
\ \ \ 9\ \ \ \ \ \ 2\ -6\ \ \ \ \ \ \ \color{black}2
-4\ \ \ \ \ \ 1\ -4\ \ \ \ \ \ \ \color{black}1
-1\ \ \ \ \ \ 8\ \ \ \ \ \ 0\ \ -2
再减去绿色部分
\color{green}\ \ \ 0\color{black}\ -2\ -7\ \ \ \ \ \ \ 0
\color{green}\ \ \ 9\color{black}\ \ \ \ \ \ 2\ -6\ \ \ \ \ \ \ 2
\color{green}-4\color{black}\ \ \ \ \ \ 1\ -4\ \ \ \ \ \ \ 1
-1\color{black}\ \ \ \ \ \ 8\ \ \ \ \ \ 0\ \ -2
加上黄色部分
\color{yellow}\ \ \ 0\color{black}\ -2\ -7\ \ \ \ \ \ \ 0
\ \ \ 9\ \ \ \ \ \ 2\ -6\ \ \ \ \ \ \ \color{black}2
-4\ \ \ \ \ \ 1\ -4\ \ \ \ \ \ \ \color{black}1
-1\ \ \ \ \ \ 8\ \ \ \ \ \ 0\ \ -2
就变成了上面的红色部分。
那么假设红色部分左上角坐标为(x1,y1),右下角为(x2,y2),设sum[x][y]表示从(1,1)加到(x,y)的和,那么红色部分就是:
sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]
(可以自己理解一下)
那么sum[x][y]要怎么求呢?
其实就是x这一行到y的前缀和加上sum[x-1][y]就Ok啦~~
可以自己理解一下(应该很好理解吧)
然后呢,再用4个变量循环判断坐标,然后求最大值即可。
代码如下:
#include<iostream>
using namespace std;
int n;
int a[130][130];//存储题目中的矩阵
int sum[130][130];
int qz[130][130];//qz[i][j]指的是第i行到j的前缀和
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
qz[i][j]=qz[i][j-1]+a[i][j];//求前缀和
sum[i][j]=qz[i][j]+sum[i-1][j];//计算sum
}
}
int mx=-99999999;//存储答案
for(int x1=1;x1<=n;x1++){
for(int y1=1;y1<=n;y1++){
for(int x2=1;x2<=n;x2++){
for(int y2=1;y2<=n;y2++){
if(x2<x1 || y2<y1) continue;//如果左上角比右下角还要大,就不用求了,下一个
mx=max(mx,sum[x2][y2]+sum[x1-1][y1-1]-sum[x2][y1-1]-sum[x1-1][y2]);//求最大值
}
}
}
}
cout<<mx;//输出
return 0;
}