• 最大子列和求解


    题目如下:

    Snipaste_2019-10-31_18-07-15.png

    Snipaste_2019-10-31_16-12-58.png

    四种解题思路对应的完整代码如下:

    //最大子列和求解思路
    
    #include<iostream>
    #include<cstdio>
    using namespace std;
    int maxsubseqsum1(int nums[],int size);
    
    int maxsubseqsum2(int nums[],int size);
    
    int maxsubseqsum3(int nums[],int size);
    
    int maxsubseqsum4(int nums[],int size);
    
    void begin();
    
    int main() {
    	int switchflag=1;
    	while(switchflag==1){
    		begin();
    		cout<<"输入1继续下一次计算,输入其他按键退出:";
    		cin>>switchflag;
    	}
    	exit(1);
    }
    
    void begin(){
    	int size,i;
    	int maxsum;
    	cout<<"请输入整数个数(1-100):";
    	cin>>size;
    	while(size<1||size>100) {
    		cout<<"请输入1-100范围内的整数:";
    		cin>>size;
    	}
    	int nums[size];
    	for(i=0;i<size;i++){
    		cout<<"请输入第"<<i+1<<"个整数:";
    		cin>>nums[i];
    	}
    	maxsum = maxsubseqsum1(nums,size);
    	cout<<"思路一:"<<maxsum<<endl;
    
    	maxsum = maxsubseqsum2(nums,size);
    	cout<<"思路二:"<<maxsum<<endl;
    
    	maxsum = maxsubseqsum3(nums,size);
    	cout<<"思路三:"<<maxsum<<endl;
    
    	maxsum = maxsubseqsum4(nums,size);
    	cout<<"思路四:"<<maxsum<<endl;
    } 
    
    //思路一,左边界i,右边界j,确定范围之后,再遍历i...j求和,时间复杂度T(n) =O(n^3)
    int maxsubseqsum1(int nums[],int size) {
    	int i,j,k;
    	int sum,thissum;
    	sum=0;
    	//子列的左边 0.....size-1
    	for(i=0; i<size; i++) {
    		//子列的右边 i....size-1
    		for(j=i; j<size; j++) {
    			thissum=0;
    			//循环累加求和i...j
    			for(k=i; k<=j; k++) {
    				thissum+=nums[k];
    			}
    			if(thissum>sum) {
    				sum=thissum;
    			}
    		}
    
    	}
    	return sum;
    }
    
    //基于思路一进行改进,每次右边界右移一个单位时,不再重新开始累加求和,直接在之前的基础上累加,也就是同一个左边界i,对于右边界j右移时,计算一次加法运算即可
    //时间复杂度T(n)=O(n^2)
    int maxsubseqsum2(int nums[],int size) {
    	int i,j;
    	int sum,thissum;
    	sum=0;
    	//子列的左边 0.....size-1
    	for(i=0; i<size; i++) {
    		//子列的右边 i....size-1
    		thissum=0;//同一个左边界i
    		for(j=i; j<size; j++) {
    			thissum+=nums[j];
    			//循环累加求和i...j
    
    			if(thissum>sum) {
    				sum=thissum;
    			}
    		}
    
    	}
    	return sum;
    }
    
    //返回3个整数中的最大的一个
    int getmaxint3(int a,int b,int c) {
    	return a>b?(a>c?a:c):(b>c?b:c);
    }
    
    //递归调用分治思想的核心代码
    int dividegovern(int nums[],int left,int right) {
    	//左右最大子列和
    	int MaxLeftSum, MaxRightSum;
    	
    	//跨边界左右最大子列和
    	int MaxLeftBorderSum, MaxRightBorderSum;
    	
    	//当前计算的左右边界子列和
    	int LeftBorderSum, RightBorderSum;
    	
    	int center, i;
    
    	//递归调用终止条件,子列只有一个元素
    	if( left == right )  {
    		if( nums[left] > 0 )  return nums[left];
    		else return 0;
    	}
    
    	//先分
    	center = ( left + right ) / 2; 
    	//递归调用获取左边最大子列和 left.....center 
    	MaxLeftSum = dividegovern( nums, left, center );
    	
    	//递归调用获取右边最大子列和 center+1.....right
    	MaxRightSum = dividegovern( nums, center+1, right );
    
    	//跨边界最大子列和 
    	MaxLeftBorderSum = 0;
    	LeftBorderSum = 0;
    	for( i=center; i>=left; i-- ) { /* 从中线向左扫描 */
    		LeftBorderSum += nums[i];
    		if( LeftBorderSum > MaxLeftBorderSum )
    			MaxLeftBorderSum = LeftBorderSum;
    	} /* 左边扫描结束 */
    
    	MaxRightBorderSum = 0;
    	RightBorderSum = 0;
    	for( i=center+1; i<=right; i++ ) { /* 从中线向右扫描 */
    		RightBorderSum += nums[i];
    		if( RightBorderSum > MaxRightBorderSum )
    			MaxRightBorderSum = RightBorderSum;
    	} /* 右边扫描结束 */
    
    	/* 下面返回"治"的结果 */
    	return getmaxint3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
    }
    
    //思路三,分而治之,先分后治,采用递归的思想
    //时间复杂度为T(n)=O(nlogn)
    int maxsubseqsum3(int nums[],int size) {
    	return dividegovern(nums,0,size-1);
    }
    
    //思路四,在线处理
    //时间复杂度T(n) =O(n)
    int maxsubseqsum4(int nums[],int size) {
    	int sum , thissum,i;
    	sum=0;
    	thissum=0;
    	for(i=0;i<size;i++){
    		thissum+=nums[i];
    		if(thissum>sum){
    			sum=thissum;
    		}
    		if(thissum<0){
    			thissum=0;
    		}
    	}	
    	return sum;
    }
    
    
  • 相关阅读:
    有一群志同道合的程序员朋友是怎样的体验?
    hdu1387 模拟队列
    hau 1870 愚人节的礼物(栈)
    hdu1509 优先队列
    hdu1837 看病要排队(优先队列)
    hdu 1237 简单计算器(栈处理)
    hdu1022 模拟栈
    又一个错误的认知!
    jmeter+ant+jenkins 接口自动化测试持续集成(送源码)
    P1197 [JSOI2008]星球大战
  • 原文地址:https://www.cnblogs.com/ericling/p/11773903.html
Copyright © 2020-2023  润新知