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;
}