UVa 10360 - Rat Attack

本文探讨了如何通过动态规划优化算法解决在矩阵中寻找元素加和最大的子矩阵的问题,包括矩阵预处理、枚举技巧以及复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:在一个矩阵中,寻找一个元素加和最大的子矩阵。

分析:简单题、暴力枚举。如果直接暴力时间复杂度为O (t*n^2*d^2),所以要利用dp做预处理。矩形用左上和右下两个顶点描述,即{(x1,y1),(x2,y2)}。设f(i,j)为矩形{(0,0),(i,j)}的元素之和,则矩形{(x1,y1),(x2,y2)}的元素和为f(x2,y2)-f(x1,y2)-f(x2,y1)+f(x1,y1)。时间复杂度为O(t*n^2)。

注意:枚举的范围是 [0,max_x] 和 [0,max_y]。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int rat[ 1030 ][ 1030 ];
int sum[ 1030 ][ 1030 ];

int main()
{
	int t,d,n,x,y,r; 
	while ( scanf("%d",&t) != EOF )
	while ( t -- ) {
		scanf("%d%d",&d,&n);
		memset( rat, 0, sizeof( rat ) );
		int min_x = 1025,max_x = 1;
		int min_y = 1025,max_y = 1;
		for ( int i = 0 ; i < n ; ++ i ) {
			scanf("%d%d%d",&x,&y,&r);
			++ x; ++ y;//范围[1,1025])
			rat[ x ][ y ] = r;
			if ( x < min_x ) min_x = x;
			if ( x > max_x ) max_x = x;
			if ( y < min_y ) min_y = y;
			if ( y > max_y ) max_y = y;
		}
		//预处理
		memset( sum, 0, sizeof( sum ) );
		for ( int i = min_x ; i <= max_x ; ++ i ) {
			int sum_y = 0;
			for ( int j = min_y ; j <= max_y ; ++ j ) {
				sum_y += rat[ i ][ j ];
				sum[ i ][ j ] = sum_y;
				if ( i > min_x )
					sum[ i ][ j ] += sum[ i-1 ][ j ];
			}
		}
		
		int max = 0;
		int xxx = 0;
		int yyy = 0;
		for ( int i = 0 ; i <= max_x ; ++ i ) 
			for ( int j = 0 ; j <= max_y ; ++ j ) {
				int lu_x = i-d-1,rd_x = i+d;
				int lu_y = j-d-1,rd_y = j+d;
				if ( lu_x < 0 ) lu_x = 0;
				if ( lu_y < 0 ) lu_y = 0;
				if ( rd_x > max_x ) rd_x = max_x;
				if ( rd_y > max_y ) rd_y = max_y;
				int now = sum[ rd_x ][ rd_y ] 
						- sum[ rd_x ][ lu_y ]
						- sum[ lu_x ][ rd_y ]
						+ sum[ lu_x ][ lu_y ];
				if ( max < now ) {
					max = now;
					xxx = i-1;
					yyy = j-1;
				}
			}
		printf("%d %d %d\n",xxx,yyy,max);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值