最大连通子数组
这次是求联通子数组的求和,我们想用图的某些算法,比如迪杰斯特拉等,但是遇到了困难。用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;
}
这种方法只能在某些情况下可以实现,更加完整的我们还在完善。