最大连通数组的和
这次是求联通子数组的求和,我们想用图的某些算法,比如迪杰斯特拉等,但是遇到了困难。
那么我们这样想,先将每行的最大子数组之和,然后再将这些最大之和组成一个数组,在进行求和,这样就保证了,加入中间一行为负数,再进行筛选。增加了直接相加的正确率。
实现代码:
1 #include <iostream> 2 #include <fstream> 3 using namespace std; 4 int Max(int Array[],int length) 5 { 6 int maxSumOfArray,maxSum; 7 int first=0,last=1; 8 maxSumOfArray=maxSum=Array[0]; 9 //当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。 10 //如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和。 11 for(int i=1;i<length;i++) 12 { 13 maxSumOfArray=max(maxSumOfArray+Array[i],Array[i]); //变量maxSumOfArray 为包含Array[i] 与Array[i] 取最大 14 maxSum=max(maxSum,maxSumOfArray); ////变量maxSum 为maxSum 与 maxSumOfArray 取最大 15 } 16 cout<<"最大子数组和:"<<maxSum<<endl; 17 return maxSum; 18 } 19 int main() 20 { 21 int a; 22 int i=0,j=0; 23 int b[10][10],c[10]; 24 FILE * fp1 = fopen("E:\\input.txt", "r");//打开输入文件 25 if (fp1==NULL) {//若打开文件失败则退出 26 puts("不能打开文件!"); 27 return 0; 28 } 29 30 int M,N; 31 fscanf(fp1,"%d",&a); 32 M=a; //行 33 cout<<"行数:"<<M<<endl; 34 fscanf(fp1,"%d",&a); 35 N=a; //列 36 cout<<"列数:"<<N<<endl; 37 for (i=0;i<M;i++) 38 { 39 for(j=0;j<N;j++) 40 { 41 if(fscanf(fp1,"%d",&a)==1) 42 { 43 b[i][j]=a; 44 cout<<b[i][j]<<" "; 45 } 46 } 47 cout<<endl; 48 } 49 cout<<"文件已经读取到第 "<<ftell(fp1)<<" 个偏移字节"<<endl;//输出fp1指针当前位置相对于文件首的偏移字节数 50 fclose(fp1);//关闭输入文件 51 int thismax[10]; //存放数组每行的最大子数组 52 cout<<"每行的最大数组和:"<<endl; 53 for(i=0;i<M;i++) 54 { 55 for(j=0;j<N;j++) 56 { 57 c[j]=b[i][j]; 58 } 59 thismax[i]=Max(c,N); 60 } 61 cout<<"每行的最大子数组之和再求和"<<endl; 62 int sum=Max(thismax,M); //每行作为一个数组再求最大的子数组和 63 cout<<"最大联通子数组的和为:"<<sum<<endl; 64 return 0; 65 }
测试文件的内容以及运行效果:
另一组测试数据:
虽然在某些数组的求和上可以正确,我们还在改进。。。
结对小伙伴博客地址:http://www.cnblogs.com/L-Damon-v/