最大子数组和04

1、题目要求:

  返回一个二维数组中最大连通子数组的和

    从input.txt 文件中读入一个二维整形数组,数组里有正数也有负数。

2、实现思路:

  (1)先要能够读入txt 文档中的各数的值;

  (2)将读出的行数、列数、数组中的数分别保存;

  (3)每一行都存在一个最大的子数组和;

  (4)将每行最大的子数组和以最小的代价连接起来,将代价与各个和加在一起,可以得出最大值

3、思路整理(实现步骤):

  (1)读入txt 文档中的各数的值,第一行是行数,存给 line ,第二行是列数,存到row,剩下的数存入数组array【】【】中;

  (2)从第一行开始,按照前几次实验的方法,找出每一行中的最大子数组和,存入array2【】中;并找到这个最大子数组和的数组的最小下标min_i 和最大下标max_i 分别存入mini【】和maxi【】中;

  (3)将每一行中的最大最小下标与下一行的最小最大下标相比,联通,则这两行的最大子数组和为两行的最大子数组和相加;

  (4)若不能联通,选择一个最小代价路径使其联通;

  (5)看有无其他的正数与这一条联通的线相连,若有,加到总和上。

4、源代码:

 

  1 #include <iostream>
  2 #include <fstream>
  3 #include <string>
  4 using namespace std ;
  5 
  6 
  7 int maxcount(int n,int a[],int *min_i,int *max_i)//求一行中的最大子数组和
  8 {
  9     int b[100]={0};
 10     int i,sum=0,max=0;
 11     for(i=0;i<n;i++)
 12     {
 13         if(sum<0)
 14         {
 15             sum=a[i];
 16         }
 17         else
 18         {
 19             sum=sum+a[i];
 20         }
 21         b[i]=sum;
 22     }
 23     max=b[0];
 24     for(i=0;i<n;i++)
 25     {
 26         if (max<b[i])
 27          {
 28              max= b[i];
 29              *max_i = i;
 30          }
 31     }
 32      for (i = *max_i;i >= 0;i--)
 33     {
 34         if (b[i] == a[i])
 35         {
 36              *min_i = i;
 37              break;
 38         }
 39     }
 40      return max;
 41 }
 42 
 43 
 44 int main()
 45 {
 46     int i,j;
 47     char str[1024] ;
 48     ifstream infile( "D:\\input.txt" );//文件位置
 49     if ( !infile.good() )
 50     {
 51         cout <<"    打开文件“D:\\input.txt”失败! \n 请检查文件路径下是否存在该文件!\n" ;
 52         return -1;
 53     }
 54     int line,row;
 55     int array[100][100],array2[100];//数组array 是二维数组,array2 是每行的最大子数组和组成的数组
 56     infile.getline( str, sizeof(str) );//获取行数
 57     sscanf( str , "%d" , &line);
 58     infile.getline( str, sizeof(str) );//获取列数
 59     sscanf( str , "%d" , &row );
 60     cout <<"  二维数组共 "<< line <<""<< row<<""<<endl<<endl;
 61     cout <<"  二维数组: "<< endl;
 62     for(i=0;i<line;i++)//读取二维数组
 63     {    
 64         for(j=0;j<row;j++)
 65         {
 66             infile>>array[i][j];
 67         }
 68     }
 69     for(i=0;i<line;i++)//输出二维数组
 70     {    
 71         cout <<"\t";
 72         for(j=0;j<row;j++)
 73         {
 74             cout << array[i][j]<<"\t" ;
 75         }
 76         cout <<endl;
 77     }
 78     infile.close();
 79 
 80 
 81     int min_i;
 82     int max_i;//最大子数组和数的下标
 83     int countmax;//最大子数组的和数的下标
 84     int sum,max;
 85     int mini[100],maxi[100],t[100];
 86      for(i=0;i<line;i++)
 87     {
 88         for(j=0;j<row;j++)
 89         {
 90             array2[j]=array[i][j];
 91         }
 92         sum=maxcount(row,array2,&min_i,&max_i);
 93         mini[i]=min_i;   // 保存最大和子数组的最小下标                        
 94         maxi[i]=max_i;     // 保存最大和子数组的最大下标     
 95         t[i]=sum;
 96     }
 97     countmax=t[0];
 98     for(i=0;i+1<line;i++)
 99     {
100         if(mini[i]<=maxi[i+1] && maxi[i]>=mini[i+1])
101         {
102             countmax+=t[i+1];
103         }
104 
105          for(j=mini[i];j<mini[i+1];j++)
106         {
107             if(array[i+1][j]>0) //判别剩下的单独正数
108             {
109                 countmax+=array[i+1][j];
110             }                   
111         }
112     }
113      cout<<"\n    最大联通子数组和为:"<<countmax<<endl<<endl;
114     return 0;
115 }

 

 

5、运行结果:

    

 

                         项目计划日志(单位:h):

  听课 编写程序 阅读相关书籍 网上查找资料   日总计
周六  0 2 0  0.5 2.5
周日  0 2  1  1  4
周一 0 2 0 1 3

                         时间记录日志(单位:min):

日期 开始时间 结束时间 中断时间 净时间 活动 备注
星期六 8:00 11:30 30(洗漱) 150 查资料,编程  
星期日 8:30 11:00   140 查资料,编程  
  15:00 18:00   100 编程  
星期一 8:30 11:00   160 查资料,编程  

队友地址:http://www.cnblogs.com/mengyinianhua/

posted @ 2016-04-06 15:42  David~Wang  阅读(175)  评论(1编辑  收藏  举报