zoukankan      html  css  js  c++  java
  • 联通子数组最大值设计03

    So郁闷,我先把老师提出的问题写出来;

    返回一个二维整数数组中最大联通子数组的和。

    要求:

    输入一个二维整形数组,数组里有正数也有负数。

    求所有子数组的和的最大值。下面是给的示例图:

     

    最近已经完全的陷入了编程的怪圈,自己完全没找到自己的方向吧,废话不多说,直接上问题:在子数组问题上我觉得基本都是一位子数组的变形,应该不会有特别的变化,最多是难度上去,但是基本的思想不会变,今天我发现错了,可能是我错了。

    我的想法:在网上看代码找到的灵感:因为觉得老师上课讲的图的方法有些麻烦所以就想还是用一维数组的方法AC。开始就是找二维数组中每个一维数组的最大子数组的起始点,然后看能否联通,能联通就直接相加,不能连就去找一条能联的路径,最后加一种特殊的情况,就好了。然而到了真正重新考虑这个模糊的找一条代价最小的路径,我茫然了,这还是需要用图来解决吧。先把代码贴出来,后面一定把问题完善一下,如果有好的建议就请@我,谢谢。

     

    #include<iostream>
    using namespace std;
    
    void max_place(int row,int &max,int fl[],int &start,int &end);
    
    int main()
    {
    	int a[100][100];
    	int fl[100];
    	int hang=0,lie=0;
    	int start_k[100],end_k[100];    //定义二维数组中每一次起始终止位置
    	int large[100];
    	int max=0;
    	int start=0,end=0;    //位置参数
    	cout<<"请输入数组行列数:"<<endl;
    	cin>>hang>>lie;
    	 int i=0,j=0;
    	for(i=0;i<hang;i++)
    		for(j=0;j<lie;j++)
    		{
    			cin>>a[i][j];
    		}
    
    	 for(i=0;i<hang;i++)
    		{
    			for(j=0;j<lie;j++)
    		{
    			cout<<a[i][j]<<" ";
    		}
    			cout<<endl;
    	 }
    
    		//对于数组找到最大联通数组的和
    		for(i=0;i<hang;i++)
    		{
    			
    			for(j=0;j<lie;j++)
    			{
    				fl[j]=a[i][j];
    				
    			}
    			max_place(lie,max,fl,start,end);
    
    			cout<<"开始位置:"<<start<<" "<<end<<endl;
    			cout<<"最大值为:"<<max<<endl;
    			start_k[i]=start;
    			end_k[i]=end;
    			large[i]=max;
    		}
    
    		int max2=large[0];
    		//找到连同数组的情况:分情况讨论
    		for(i=0;i<hang-1;i++)
    		{
    			//若上下数组行联通
    			if((start_k[i+1]<=end_k[i])&&(start_k[i]<=end_k[i+1]))
    			{
    				max2+=large[i+1];
    			}
    			//上下不联通考虑最小代价
    			//第一行在第二行右边
    			if(start_k[i]>=end_k[i+1])
    			{
    				int p=large[i+1]+large[i];
    				int r1=0,r2=0,r=0;
    				//两种判断
    				for( j=end_k[i+1]+1;j<=start_k[i];j++)
    				  r1+=a[i][j];
    				for( j=end_k[i+1]+1;j<start_k[i];j++)
    				  r2+=a[i][j];
    
    				r2=r2+a[i][end_k[i+1]+1];
    				r=r1;
    				if(r2>r1)
    					r=r2;
    
    				if(p+r>p)
    				max2=max2+p+r;
    			}
    			//第一行在第二行左边
    			if(start_k[i+1]>=end_k[i])
    			{
    				int p=large[i+1]+large[i];
    				int r=0;
    				for( j=end_k[i]+1;j<start_k[i+1];j++)
    				  r+=a[i][j];
    				for( j=end_k[i+1]+1;j<start_k[i+1];j++)
    				  r+=a[i][j];
    
    
    				if(p+r>p)   //如果存在更新判断域
    				max2=max2+p+r;
    			}	
    			//单独正数的情况
    			for(j=start_k[i];j<start_k[i+1];j++)
    			{
    				if(a[i+1][j]>0)
    					max2+=a[i+1][j];
    			}
    		}
    		cout<<"最大值为"<<max2<<endl;
    	return 0;
    }
    
    //找到二维数组中每一行最大的值的起始位置
    void max_place(int row,int &max,int fl[],int &start,int &end)
    {
    	//求每个一维数组的最大值
    	int b[100]={0},s=0;   //存放最大值
    	//finding
    	for(int i=0;i<row;i++)
    	{
    		if(s>=0)
    		{
    			s+=fl[i];
    		}
    		else
    		{
    			s=fl[i];
    		}
    		b[i]=s;
    	}
    
    	//
    	int max_num=b[0];
    	for(int i=0;i<row;i++)
    	{
    		if(b[i]>max_num)
    		{
    			max_num=b[i];
    			end=i;     //末位置
    		}
    	}
    
    	for(int i=end;i>=0;i--)
    	{
    		if(fl[i] == b[i])
    		{
    			start=i;    //找到首位置
    		   break;
    		}
    	}
    	max=max_num;   //返回最大值
    }
    

      

      近期完善,谢谢

  • 相关阅读:
    jquery中ajax请求的使用和四个步骤示例
    jzoj6094
    2019.03.27【GDOI2019】模拟 T3
    AGC019F
    浅谈高维前缀和
    刷题清单
    为什么要遍历两次?——个人对于kosaraju算法的理解
    我的黑客和渗透测试学习路线
    一个假猪套神器:NET CAT-NC
    kali linux(二):使用与介绍
  • 原文地址:https://www.cnblogs.com/ly199553/p/5357135.html
Copyright © 2011-2022 走看看