还是动态规划
题目大意:
给定一个N*N的矩阵,在矩阵中寻找一个h*w的矩阵,使得对于所有可能的矩阵,这个矩阵的所有元素和最大,并输出这个最大值。
-------------------------------------------------割啊割啊割啊割啊割啊割------------------------------------------------------
额,一开始呢,我觉得这是一道蛮有挑战性的题目...结果...
其实一开始我还是分析了这题目的子结构什么的,结果发现,这道题可以直接转换成一维的最大子序列和问题。转换的关键就是,对于同一列,按照不同的方式求和(当然上下保证要连续的),然后将同一种求和方式排成一行,对这一行求取最大子序列和,遍历完所有的求和方式,就OK了...
当然你也可以对于每一行来做这个,不过由于计算机存储方式的关系,用行的话会增加缓存的换入换出,减少缓存的命中率。速度会变慢的。
好了,其实这道题没有什么新鲜的东西,唯一说一下的就是在内存的限制下,需要节约空间来做这个。
直接上代码吧。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_L 100
//(2*100^2)*4+100= 80000 = 80k
int a[MAX_L][MAX_L];
int sum[MAX_L][MAX_L];
int totalMax=-12800; //保存最终结果的,求和最小值不会超过-127*100
int findMax(int N){
int rowP[MAX_L]; //临时数组
int max,i,j;
int *sumRowP,*rowA;
int row;
for (row=0;row<N;row++){
for (i=0;i<(N-row);i++){
sumRowP=sum[i];
rowA=a[row+i];
for (j=0;j<N;j++){ //s(i,j)代表在输入矩阵中,以第i行第j个元素为起始,垂直长度为row+1的列的和。
sumRowP[j]+=rowA[j];
}
rowP[0]=sumRowP[0]; //问题转化成,在这个行中,求最大子序列的问题
for (j=1;j<N;j++){ //一维最大子序列和的问题
if (rowP[j-1]<0){
rowP[j]=sumRowP[j];
}else{
rowP[j]=rowP[j-1]+sumRowP[j];
}
}
max=-12800;
for (j=0;j<N;j++){
if (rowP[j]>max)
max=rowP[j]; //求出的max就是在垂直长度为row+1的所有矩形中,矩形内元素和的最大值
}
if (totalMax<max)
totalMax=max; //保存最终结果的
}
}
}
int main(){
int N,i,j;
scanf("%d",&N);
for (i=0;i<N;i++){
for (j=0;j<N;j++){
scanf("%d",&a[i][j]);
}
}
memset(sum,0,MAX_L*MAX_L*sizeof(int));
findMax(N);
printf("%d",totalMax);
return 0;
}
就这样~加油!
![奋斗](http://static.blog.csdn.net/xheditor/xheditor_emot/default/struggle.gif)