zoukankan      html  css  js  c++  java
  • 最大子数组和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”失败! 
     请检查文件路径下是否存在该文件!
    " ;
     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 <<"	";
     72         for(j=0;j<row;j++)
     73         {
     74             cout << array[i][j]<<"	" ;
     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<<"
        最大联通子数组和为:"<<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/

  • 相关阅读:
    JZOJ 3034. 【NOIP2012模拟10.17】独立集
    JZOJ 3035. 【NOIP2012模拟10.17】铁轨
    JZOJ 1259. 牛棚安排
    数位DP JZOJ 3316. 非回文数字
    JZOJ 3046. 游戏
    JZOJ 3013. 填充棋盘
    debian 安装oracle提供的java8
    java 汉字转拼音 PinYin4j
    debian ssh设置root权限登陆 Permission denied, please try again
    java并发下订单生成策略
  • 原文地址:https://www.cnblogs.com/wangyw/p/5359595.html
Copyright © 2011-2022 走看看