NOJ [1445] Lottery Draw

  • 问题描述
  • 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;
    }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值