NYOJ104——动态规划的运用

每一道题目,只要你愿意耐心的去发现它的思路,你会发现其中其乐无穷。

题目非常简单,就是求一个子矩阵使得其各项的和最大。

在这里我们先回想一下求一个数组的最大连续字串和,假定一整形数列{a1,a2,a3,...,an},找出连续的非空子串{ax,ax+1,ax+2,...,ax+y},使得该子序列的的和最大。思路:假设F[m]表示以第m个数结尾的最大连续字串和,则F[m]=max{F[m-1],0}+a[m],然后再求出F[m]数组中的最大值即可,代码为:

maxsum=-INT_MAX;
scanf("%d",&m);
for(int i=1;i<=m;++i)
{
	scanf("%d",&a[i]);
	if(a[i-1]>0) a[i]+=a[i-1];
	if(a[i]>maxsum) maxsum=a[i];
}
	
printf("%d\n",maxsum);


联系本题,即将二维转化为一维,分析如下:

假设最大子矩阵的结果为从第r行到k行、从第i列到j列的子矩阵,如下所示(ari表示a[r][i],假设数组下标从1开始):
  | a11 …… a1i ……a1j ……a1n |
  | a21 …… a2i ……a2j ……a2n |
  |  .     .     .    .    .     .    .   |
  |  .     .     .    .    .     .    .   |
  | ar1 …… ari ……arj ……arn |
  |  .     .     .    .    .     .    .   |
  |  .     .     .    .    .     .    .   |
  | ak1 …… aki ……akj ……akn |
  |  .     .     .    .    .     .    .   |
  | an1 …… ani ……anj ……ann |

那么我们将从第r行到第k行的每一行中相同列的加起来,可以得到一个一维数组如下:
(ar1+……+ak1, ar2+……+ak2, ……,arn+……+akn)
由此我们可以看出最后所求的就是此一维数组的最大子断和问题,到此我们已经将问题转化为上面的已经解决了的问题了。

在此插入代码,仔细分析一下三个for循环,便可发现这道题也是挺easy的
 
#include<stdio.h>
#include<string.h>

const int MAX=102;
int arr[MAX][MAX];
//定义参数max接收最大值
int max;

int row,col;
//得到每一行连续的最大值
void getMax(int a);

int main()
{
	//freopen("in.txt","r",stdin);
	int n;
	scanf("%d",&n);
	while(n--)
	{
		memset(arr,0,sizeof(arr));
		scanf("%d%d",&row,&col);
		for(int i=1;i<=row;++i)
		{
			for(int j=1;j<=col;++j)
			{
				scanf("%d",&arr[i][j]);
			}
		}

		max=arr[1][1];
		for(int i=1;i<=row;++i)
		{
			getMax(i);//获得第i行的最大连续子串和
			for(int j=i+1;j<=row;++j)
			{
				for(int k=1;k<=col;++k)
					arr[i][k]+=arr[j][k];
				getMax(i);//获得第i行至第j行的最大连续子串和
			}
		}
		printf("%d\n",max);	
	}
}

void getMax(int a)
{
	int temp=0;			
	for(int i=1;i<=col;++i)
	{
		if(temp>0)
			temp+=arr[a][i];
		else
			temp=arr[a][i];
		if(temp>max)
			max=temp;
	}
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值