POJ 1050

还是动态规划

题目大意:

给定一个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;
}

就这样~加油! 奋斗

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值