- 问题描述
-
Now, there is a new play about lottery draw.
Give you a matrix with N * N integers, you can choose a A * B(0 <= A, B <= N) rectangle to box a part of the matrix, if the higher the sum of these integers in the rectangle are, the more you might win a prize in a lottery.
So, can you find the maximum sum in the matrix? You can also give up this time for getting 0.
- 输入
-
Input until EOF.
Each test contains a integet N (4 <= N <= 100) and a N * N matrix, each integer will be in [-99, 99].
- 输出
-
Print the maximum sum.
最大权值子矩阵,思想其实很简单下面我来介绍下首先,我们得计算出一个SUM[I][J],表示第J列从第1行开始到第I行的和,这个有什么用呢,待会说知道列的和,但我们不知道矩阵的上界和下界,这时我们可以枚举上下界,但这样还不够,因为光知道上下界,还不能得到矩阵的总和,我们不妨再开一个数组array[i],来记录前i列的和,那么只要找到一组 array[j]-array[i]最大,这就是最大子矩阵的和了所以,array[i]可以根据SUM数组飞快地求出,如果还不理解,请看下回分解~~~开个玩笑,看图
这样就把二维的问题转换成一维的了;
这是我AC的代码,供大家参考#include<stdio.h> #include<string.h> #define inf -0x3f3f3f3f int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int mat[105][105],sum[105][105],array[105]; int main() { int n,i,j,up,down,ans; while(~scanf("%d",&n)) { memset(sum,0,sizeof(sum)); for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&mat[i][j]); for(i=1;i<=n;i++) for(j=1;j<=n;j++) sum[i][j]=sum[i-1][j]+mat[i][j];//这个数组表示第j列,从1到i 的和 //枚举矩阵的上下边界 array[0]=0; ans=inf; for(up=1;up<=n;up++) for(down=up;down<=n;down++) { for(i=1;i<=n;i++) array[i]=array[i-1]+sum[down][i]-sum[up-1][i];//array是前i列的值,这是上下界确定,所以只要找到一个arra[t1]-array[t2]最大,那么就是最大权值矩阵 int minx=0; for(i=1;i<=n;i++) { ans=max(ans,array[i]-minx); minx=min(minx,array[i]); } } printf("%d\n",ans); } return 0; }
NOJ [1445] Lottery Draw
最新推荐文章于 2022-07-08 09:54:12 发布