首页 > 其他分享 >顺序表应用7:最大子段和之分治递归法

顺序表应用7:最大子段和之分治递归法

时间:2024-06-05 22:59:46浏览次数:32  
标签:count 递归 子段 int 分治 fib ans

Description

给定n(1<=n<=50000)个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n。 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。

注意:本题目要求用分治递归法求解,除了需要输出最大子段和的值之外,还需要输出求得该结果所需的递归调用总次数。

递归调用总次数的获得,可以参考以下求菲波那切数列的代码段中全局变量count的用法:

#include
int count=0;
int main()
{
int n,m;
int fib(int n);
scanf("%d",&n);
m=fib(n);
printf("%d %d\n",m,count);
return 0;
}
int fib(int n)
{
int s;
count++;
if((n==1)||(n==0)) return 1;
else s=fib(n-1)+fib(n-2);
return s;
}

Input

第一行输入整数n(1<=n<=50000),表示整数序列中的数据元素个数;

第二行依次输入n个整数,对应顺序表中存放的每个数据元素值。

Output

一行输出两个整数,之间以空格间隔输出:

第一个整数为所求的最大子段和;

第二个整数为用分治递归法求解最大子段和时,递归函数被调用的总次数。

Samples

Sample #1
Input 

6 -2 11 -4 13 -5 -2

Output 
20 11
#include <bits/stdc++.h>
using namespace std;
int n,a[50005],cnt=0;
int getson(int l,int r,int mid){
    //计算在给定范围 [l, r] 内以 mid 为中间位置的子数组的最大子数组和
	int s1=0,s2=0,ans=0;
	for(int i=mid;i>=l;i--){
		ans+=a[i];
		s1=max(s1,ans);
	}
	ans=0;
	for(int i=mid+1;i<=r;i++){
		ans+=a[i];
		s2=max(s2,ans);
	}
	return s1+s2;
}
int f(int l,int r){
	cnt++;
	if(l==r) return a[l];
	int mid=(l+r)/2;
	int x1=f(l,mid);//获取左子问题的结果x1
	int x2=f(mid+1,r);//右子问题的结果x2
	int x3=getson(l,r,mid);//getson函数计算得到的跨越中间位置的子数组和x3
	return max(x1,max(x2,x3));
    //返回 x1、x2 和 x3 中的最大值作为当前范围内的最大子数组和
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	int x=f(1,n);
	cout<<x<<" "<<max(cnt,0)<<endl;
	return 0;
}

标签:count,递归,子段,int,分治,fib,ans
From: https://blog.csdn.net/qq_63933556/article/details/139424514

相关文章

  • 【Android面试题】请你分别采用递归和非递归对二叉树进行遍历?
    请你分别采用递归和非递归对二叉树进行遍历?这道题想考察什么?1、二叉树的基本原理和遍历的方法?考察的知识点二叉树遍历的基本概念、二叉树的基本原理考生如何回答二叉树的基本概念当然可以!二叉树是一种常见的数据结构,它由一组称为节点的元素构成。每个节点可以有零个......
  • Day14 | 二叉树递归遍历
    递归遍历(必须掌握)二叉树的三种递归遍历掌握其规律后,其实很简单题目链接/文章讲解/视频讲解:https://programmercarl.com/二叉树的递归遍历.html注意前中后指的是根节点在前、中、后次序进行遍历。前序遍历#Definitionforabinarytreenode.#classTreeNode:#de......
  • 函数递归输出1~100的数字及递归的栈溢出问题
    什么是递归?递归就是函数⾃⼰调⽤⾃⼰递归中的递就是递推的意思,归就是回归的意思如果递归就像循环一样,打一个大的复杂问题转化一个小的问题,但是要与原问题相似,分解成规模较⼩的⼦问题来求解;直到⼦问题不能再被拆分,递归就结束了,所以递归的思考⽅式就是把⼤事化⼩的过程递归......
  • [学习笔记]点分治
    一、主要思想很容易理解,我们将一个树以一个节点分割成若干个子树。对于这个节点,我们以一些方式统计和改变答案,然后不断地向子树递归。那应该选择哪个节点呢?显然是重心。树的重心有一个性质:所有子树的大小小于等于当前树的大小的二分之一。也就是说,这保证了递归层数\(log_2\)的......
  • 反转链表(递归和迭代两种实现)
    1#defineIOstd::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)2#definebug(x)cout<<#x<<"is"<<x<<endl;3#include<bits/stdc++.h>4usingnamespacestd;5typedeflonglongll;6structNode{7intx......
  • C语言----递归函数,计算一个非负整数的数字之和
    intDigitSum(intn){if(n==0)//如果n为0,则停止递归,因为没有更多的数字可以添加。{return0;}else{returnn%10+DigitSum(n/10);}/*假设输入123,第一次递归,return3和DigitSum(12)DigitSum(12)......
  • 方法递归(黑马)
    publicstaticvoidmain(String[]args){test1();}publicstaticvoidtest1(){System.out.println("----test1----");test1();}publicstaticvoidtest2(){System.out.println("----test2----&......
  • C132 线段树分治 CF1814F Communication Towers
    视频链接: CommunicationTowers-洛谷|计算机科学教育新生态(luogu.com.cn)Problem-1814F-Codeforces//线段树分治O(mlognlogn)#include<iostream>#include<cstring>#include<algorithm>#include<vector>usingnamespacestd;#defineintlong......
  • 离散数学求图的回路和通路(基于邻接表,递归算法)
    网上大多是二维矩阵和循环算法,本篇则是基于邻接表的递归算法求图的回路和通路。代码如下:#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#defineok1#defineerror0#definemax255typedefcharelemtype;intcnt[5]=......
  • 十进制转换成八进制(递归)
    【问题描述】用递归算法,把任一给定的十进制正整数转换成对应的八进制数输出。【输入格式】输入一个正整数,表示需要转换的十进制数。【输出格式】输出一个正整数,表示转换之后的八进制的数。【输入样例】15【输出样例】17#include<bits/stdc++.h>usingnamespacestd;......