首页 > 技术文章 > 最大连通子数组

L-Damon-v 2016-04-06 19:45 原文

这次是求联通子数组的求和,我们想用图的某些算法,比如迪杰斯特拉等,但是遇到了困难。用BFS搜索能达到要求,但是还未能成功。

    那么我们这样想,先将每行的最大子数组之和,然后再将这些最大之和组成一个数组,在进行求和,这样就保证了,加入中间一行为负数,再进行筛选。增加了直接相加的正确率。

    实现代码:

#include <iostream>
#include <fstream>
using namespace std;
int Max(int Array[],int length)
{
    int maxSumOfArray,maxSum;  
    int first=0,last=1;
    maxSumOfArray=maxSum=Array[0];
    //当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。
    //如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和。
    for(int i=1;i<length;i++)
    {
        maxSumOfArray=max(maxSumOfArray+Array[i],Array[i]);   //变量maxSumOfArray 为包含Array[i] 与Array[i]    取最大
        maxSum=max(maxSum,maxSumOfArray);  ////变量maxSum 为maxSum 与 maxSumOfArray    取最大
    }
    cout<<"最大子数组和:"<<maxSum<<endl;
    return maxSum;
}
int main()
{
    int a;
    int i=0,j=0;
    int b[10][10],c[10];
    FILE * fp1 = fopen("E:\\input.txt", "r");//打开输入文件
    if (fp1==NULL) {//若打开文件失败则退出
        puts("不能打开文件!");
        return 0;
    }

    int M,N;
    fscanf(fp1,"%d",&a);
    M=a;    //行
    cout<<"行数:"<<M<<endl;
    fscanf(fp1,"%d",&a);
    N=a;    //列
    cout<<"列数:"<<N<<endl;
    for (i=0;i<M;i++)
    {
        for(j=0;j<N;j++)
        {
            if(fscanf(fp1,"%d",&a)==1)
            {
                b[i][j]=a;
                cout<<b[i][j]<<" ";
            }
        }
        cout<<endl;
    }
    cout<<"文件已经读取到第 "<<ftell(fp1)<<" 个偏移字节"<<endl;//输出fp1指针当前位置相对于文件首的偏移字节数
    fclose(fp1);//关闭输入文件
    int thismax[10];  //存放数组每行的最大子数组
    cout<<"每行的最大数组和:"<<endl;
    for(i=0;i<M;i++)
    {
        for(j=0;j<N;j++)
        {
            c[j]=b[i][j];
        }
        thismax[i]=Max(c,N);
    }
    cout<<"每行的最大子数组之和再求和"<<endl;
    int sum=Max(thismax,M);  //每行作为一个数组再求最大的子数组和
    cout<<"最大联通子数组的和为:"<<sum<<endl;
    return 0;
}

这种方法只能在某些情况下可以实现,更加完整的我们还在完善。

队友 于磊http://www.cnblogs.com/cnyulei/

推荐阅读