杭电1081—动态规划To The Max

这题 的题意想必大家都知道,我就不多说了,就是一个N*N的矩阵里找一个矩形,使得矩形内的元素值相加最大...........微笑

说实话,这题开始是没思路的,当然用暴力除外,但是无疑暴力是超时的,貌似有点DP的赶脚,后来就有了一点思路

接下来分享两种做法,一种是大佬的0ms过,一种是我自己的46ms过大哭


一言不合直接上代码:

这种方法就是一遍 遍历列长度,将一定长度列上的看成一个元素。然后看成一维数组,自己求最大连续子序列,不断更新最大值就ok了

就比如返回dp(1,2)时




dp(1,2) 的意思是遍历是所有列中的1—2行的长度列上的值 如sum为 9  0  -13  2 ,然后就和求最大子序列和那样,求得在这种遍历1-2行的情况下获得的最大矩形和为9,

然后还遍历到其他所有情况,不断更新最大值...........微笑


#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
#define N1 101
int arr[N1][N1];
int N;
int dp(int n,int m)
{
	int i,j;
	int temp[N1]={0};
	for(i=1;i<=N;i++)
	{
		for(j=n;j<=m;j++)
		{
			temp[i]+=arr[j][i];//把相应行上的加起来
		}
	}
	int Max=-200;
	int sum=0;
	for(i=1;i<=N;i++)/*****
	{
		if(sum>0)
		  sum+=temp[i];
		else
		  sum=temp[i];
		if(sum>Max)
			Max=sum;/*********相当于求最大子序列和
	}
	return Max;
}
int main()
{
	int res;
	while(~scanf("%d",&N))
	{
		int i,j;
		int Max=-200;
		memset(arr,0,sizeof(arr));
		for(i=1;i<=N;i++)
			for(j=1;j<=N;j++)
				scanf("%d",&arr[i][j]);
		for(i=1;i<=N;i++)
		{
			for(j=i;j<=N;j++)
			{
				res=dp(i,j);/这里就是遍历所求矩形的长是多大,即第几行到第几行
				if(res>Max)
					Max=res;
			}
		}
		printf("%d\n",Max);
	}
	return 0;
}


大佬做法:


#include<stdio.h>  
#include<string.h>  
#define M 105  
  
int b[M][M];//  b [ i ][ j ]存的是第j列中前i行的数据之和.求 m 到 n 列的和 即b[k][n]-b[k][m-1]  
  
int main()  
{  
    int i,j,k,sum,ans,s;  
    int n;  
    while(~scanf("%d",&n))  
    {   
        memset(b,0,sizeof(b));  
        ans=0;  
        for(i=1;i<=n;i++)  
            for(j=1;j<=n;j++)  
            {  
                scanf("%d",&k);  
                b[i][j]=b[i][j-1]+k;  
            }   
        for(i=0;i<n;i++) //代码为了方便 i 从 0 开始  
        {  
            for(j=i+1;j<=n;j++)  
            {     
                sum=0;  
                for(k=1;k<=n;k++) //利用一维DP的方法求最大字串  
                {  
                    s=b[k][j]-b[k][i];  
                    if(sum+s<0)  
                        {sum=0;}  
                    else  
                        sum+=s;  
                    if(sum>ans)  
                        ans=sum;  
                }         
            }  
        }  
        printf("%d\n",ans);  
    }  
    return 0;  
}  

大佬的做法的优点就是遍历给出长度的矩形的时候不用一个一个加了,直接在输入的时候就预处理了.........大佬果然666 大笑

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值