最大子段和与最大子阵和【动态规划解法】

1.最大子段和

在一个数组中找出和最大的连续几个数。(至少包含一个数)

例如:

数组A[] = [−2, 1, −3, 4, −1, 2, 1, −5, 4],则连续的子序列[4,−1,2,1]有最大的和6.

输入格式

第一行输入一个不超过1000的整数n。

第二行输入n个整数A[i]。

输出格式

第一行输出一个整数,表示最大的和。

#include<iostream>
#include<math.h>
using namespace std;

int dp[1010];			//dp[j]表示子串的和,如果d[j-1]>0那么的d[j]=d[j-1]+a[j],否则的d[j]=a[j] 
				//因为一旦d[j-1]<0,后面的数+d[j-1]肯定<后面的数 所以dp[j]=a[j]断开以前子串和 
int ans;
int main()
{
	int n,a[1010];					//举例   a[5]={1,2,-4,2,3} 
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	ans=dp[0]=a[0];					//初始化 ans=dp[0]=1; 
	for(int j=1;j<n;j++)				//1.  j=1时  dp[0]=1>0;   dp[1]=1+2=3;
	{						//2.  j=2时  dp[1]=3>0;   dp[2]=3-4=-1;
		if(dp[j-1]>0)				//3.  j=3时  dp[2]=-1<0;  dp[3]=a[3]=-4; 
		{					//4.  j=4时  dp[3]=-4<0;  dp[4]=a[4]=2; 
			dp[j]=dp[j-1]+a[j];		//5.  j=5时  dp[4]=2>0;   dp[5]=2+3=5; 
		}
		else
		{
			dp[j]=a[j];
		}
		ans=max(dp[j],ans);			//不断寻找dp中的最大值 
	}
	cout<<ans;
}


2.最大子阵和

#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
//注意:在理解最大子段和的基础上再研究这个 
//因为题目中说明连续,所以行和列是连续的, 
int main()
{
	int n,m,a[51][51],b[51]={0},dp[51];  //a[51][51]表示矩阵,b[51]表示子矩阵的和 ,详见下面详细例子 
	int ans=-999;
	cin>>n>>m;
	for(int i=0;i<n;i++)				//举例  a[3][3]={ {1,2,3},
	{						//		 {4,5,6},	
		for(int j=0;j<m;j++)			//		{7,8,9}}
		{
			cin>>a[i][j];
		}
	}
	
	for(int st=0;st<n;st++)              //控制子阵从哪一行开始 //1.st=0 i=0 b[j]所表示的和为子阵1,2,3 
	{							 //       i=1 b[j]所表示的和为子阵有原来的 1,2,3 还有新加的4,5,6 
		memset(b,0,sizeof(b));		                 //... 
		for(int i=st;i<n;i++)	    //枚举st行下的每个子阵 //2.st=1 i=1 b[j]所表示的和为子阵4,5,6
		{						//        i=2 b[j]所表示的和为子阵有原来的 4,5,6 还有新加的7,8,9
			for(int j=0;j<m;j++)			//... 
			{																
				b[j]+=a[i][j];
			}
			memset(dp,0,sizeof(dp));
			dp[0]=b[0];
			for(int k=1;k<m;k++)			//求最大字段和算法 
			{
				if(dp[k-1]>0)
				{
					dp[k]=dp[k-1]+b[k];
				}
				else
				{
					dp[k]=b[k];
				}
				ans=max(ans,dp[k]);
			}
		}
	}
	cout<<ans;
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值