一维数组的连续子数组的最大和
题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间负责度为O(n)。
假如输入数组为{1,-2,3,10,-4,7,2,-5},我们尝试从头到尾累加其中的正数,初始化和为0,第一步加上1,此时和为1,第二步加上-2,此时和为-1,第三步加上3,此时我们发现-1+3=2,最大和2反而比3一个单独的整数小,这是因为3加上了一个负数,发现这个规律以后我们就重新作出累加条件:如果当前和为负数,那么就放弃前面的累加和,从数组中的下一个数再开始计数。
这是非常简单的一道dp,不多讲了,如果不懂,用几个列子模拟下就常容易理解了,直接上代码了!列子:2 6 -10 7 9
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
int a[1000];
int ans,n;
void maxsum()
{
int sum=a[0];
ans=sum;
for(int i=1;i<n;i++)
{
sum=max(sum+a[i],a[i]);//如果 sum+a[i]反而比a[i]小,保留a[i];
ans=max(sum,ans);//保留最大的sum.
}
}
int main()
{
while(cin>>n)
{
for(int i=0;i<n;i++)
cin>>a[i];
maxsum();
cout<<ans;
}
return 0;
}
求二维数组的连续子数组的最大和
思路:把2维数组转换成1维数组,通过枚举它所有可能组成的行,在把这些行看成是一行,用一维数组的方法来做。讲的是比较抽象,还是代码上注释吧!
这里写代码片
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
int n,m;
int input[100][100],columnsum[100][100];
int main()
{
while(cin>>n>>m,(n+m))
{
int t;
memset(columnsum,0,sizeof(columnsum));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>t;
input[i][j]=t;
columnsum[i+1][j]=columnsum[i][j]+t;//把i行前所有的的行对应元素加起来,便于后面枚举所有的连续行组合。
}
}
int cc=-99999;
for(int i=1;i<=n;i++)
{
for(int j=0;j<i;j++)
{ int ans;
ans=columnsum[i][0]-columnsum[j][0];//对于每个i-jcolumnsum[i][0]-columnsum[j][0]可以枚举所有的行组合。
int cmax=ans;
for(int k=0;k<=m;k++)
{
int ci=columnsum[i][k]-columnsum[j][k];//把上面的行当做一个行 看,然后就是一位求最大和了。
cmax=max(cmax+ci,ci);
ans=max(cmax,ans);//ans保留最大的cmax.
}
cc=max(cc,ans);//cc保留最大的ans,
}
}
cout<<cc<<endl;
}
return 0;
}