1维连续子数组和2维连续子数组的最大和

一维数组的连续子数组的最大和

题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间负责度为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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值