分治法求最大子段和问题
最大子段和-分治法

}
//求序列a[left]~a[right]的最大子段和
int max_sum(int a[],int left,int right)
{
int i,j,sum=0;
int s1=0,s2=0,lefts=0,rights=0;
void main()
{
int i,n,a[100],t;
printf("请输入数列的个数(<99):\n");
scanf("%d",&n);
printf("请输入数列元素:\n");
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
t=max_sum(a,1,n);
lefts=lefts+a[i];
if(lefts>s1)
s1=lefts;
}
//再求解s2
for(j=center+1;j<=right;j++)
{
rights=rights+a[j];
if(rights>=max_sum(a,left,center); //对应情况1,递归求解
rightsum=max_sum(a,center+1,right); //对应情况2,递归求解
//求解s1
for(i=center;i>=left;i--)
{
2:最大子段和在第二个序列,3:最大子段和在第一个序列与第二个序列之间。
算法(复习题)1

平均情况:设待查找的元素在数组中的概率为P,不在数组中的概率为1-P,若出现在数组中每个位置的概率是均等的为p/nT(n)=P1D1+P2D2+...+PiDi+(1-P)Dn+1=p/2+n(1-p/2)1.叙述分治算法和动态规划算法的基本思想,并比较两种算法的异同。
答:分治法将待求解的问题划分成K个较小规模的子问题,对这K个子问题分别求解,再将子问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解. 动态规划将待求解的问题分解成若干的子问题,自底向上地通过求解子问题的解得到原问题的解。
动态规划将每个子问题只求解一次并将其解保存在一个表格中,当需要再次求解此子问题时,只是简单的通过查表过的该子问题的解,避免了大量的重复计算.异同:分治法求解的问题分解后的子问题都是独立的,而使用动态规划求解的问题分解后得到的子问题往往不是相互独立的。
分治法是自顶向下用递归的方法解决问题,而动态规划则是自底向上非递归解决问题。
1.简述分治算法求解过程的三个阶段。
答:(1)划分:既然是分治,当然需要把规模为n的原问题划分为k个规模较小的子问题,并尽量使这k个子问题的规模大致相同。
(2)求解子问题:各子问题的解法与原问题的解法通常是相同的,可以用递归的方法求解各个子问题,有时递归处理也可以用循环来实现。
(3)合并:把各个子问题的解合并起来,合并的代价因情况不同有很大差异,分治算法的有效性很大程度上依赖于合并的实现。
2.叙述分治法的基本思想,并分析分治法与减治法二者的区别。
答:分治法将待求解的问题划分成K个较小规模的子问题,对这K个子问题分别求解,再将子问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解.区别:分治法是把一个大问题划分成若干个子问题,分别求解各个子问题,然后把子问题的解进行合并并得到原问题的解。
减治法同样是把一个大问题划分成若干个子问题,但是这些子问题不需要分别求解,只需求解其中的一个子问题,因而也无需对子问题的解进行合并。
最大子段和问题的简单算法

最大子段和问题的简单算法一、引言最大子段和问题(Maximum Subarray Sum Problem)是计算机科学中一个经典的问题,旨在寻找数组中的连续子数组,使得该子数组中所有元素的总和最大。
这个问题的解决方法有多种,其中包括暴力解法、分治法、动态规划等。
本篇文章将介绍一种简单且高效的解决方法——Kadane算法。
二、算法描述Kadane算法是一种基于动态规划的贪心算法,其基本思想是对于给定的数组,不断选择以当前元素结尾的最大子段和,然后将这个最大子段和更新为全局最大子段和。
算法的主要步骤如下:1. 初始化两个变量,一个是局部最大和max_ending_here,初值为数组的第一个元素;另一个是全局最大和max_global,初值为数组的第一个元素。
2. 遍历数组中的每个元素,对于当前元素,计算以当前元素结尾的最大子段和max_ending_here,然后更新全局最大和max_global。
3. 在遍历过程中,对于每个元素,都会计算出一个以该元素结尾的最大子段和,因此遍历结束后,全局最大和就是最大的子段和。
三、算法复杂度分析Kadane算法的时间复杂度为O(n),其中n是数组的长度。
因为我们需要遍历数组中的每个元素一次。
在空间复杂度方面,Kadane算法只需要常数级别的额外空间来存储两个变量,因此其空间复杂度为O(1)。
四、算法实现下面是一个用Python实现的Kadane算法:def max_subarray_sum(arr):max_ending_here = max_global = arr[0]for i in range(1, len(arr)):max_ending_here =max(arr[i], max_ending_here + arr[i])max_global =max(max_global, max_ending_here)return max_global五、结论Kadane算法是一种简单且高效的解决最大子段和问题的方法,其时间复杂度为O(n),空间复杂度为O(1)。
区间dp知识点总结

区间dp知识点总结区间动态规划以区间为基本单位,将区间问题分解为子区间问题,并通过子问题的优化解来求解原问题的最优解。
在区间动态规划中,我们通常会先对区间进行预处理,然后进行状态转移和最优解的计算,最终得出整个区间的最优解。
本文将介绍区间动态规划的基本概念、相关术语、常用技巧和应用场景,并以具体的例题进行解析,希望能够帮助读者更好地理解并掌握区间动态规划的相关知识。
一、基本概念1. 区间在区间动态规划中,区间通常是指一段连续的序列,可以是数组、字符串或其他数据结构。
如有一个长度为n的数组,通常我们可以将数组的某个子区间[i, j]表示为数组的一段连续元素,其中i和j分别为区间的左右边界。
2. 状态在区间动态规划中,状态通常用来表示问题的解空间,它是问题的一个关键要素。
状态的选择不同,可能会导致不同的算法解法。
3. 状态转移方程区间动态规划的核心是状态转移方程,它描述了问题的状态如何转移,以及如何通过子问题的最优解来求解原问题的最优解。
状态转移方程通常包括两个方面:状态之间的转移关系和状态的初始值。
4. 最优解区间动态规划通常是要求解区间范围内的最优解问题。
最优解可能是指区间的最大值、最小值、最长子序列等。
二、相关术语1. 最长上升子序列(Longest Increasing Subsequence,简称LIS)最长上升子序列是指一个序列中各个元素都严格递增的子序列,且该子序列的长度最大。
在区间动态规划中,求解最长上升子序列的长度是一个常见的问题。
2. 最大子段和(Maximum Subarray Sum)最大子段和是指一个序列中连续元素的和中最大的值。
在区间动态规划中,求解最大子段和也是一个常见的问题。
3. 背包问题背包问题是一类经典的组合优化问题,它包括 0-1 背包问题、多重背包问题、分组背包问题等。
在区间动态规划中,背包问题的求解也是一个重要的应用场景。
4. 字符串处理字符串处理是区间动态规划中一个重要的应用场景,常见的问题包括编辑距离、最长公共子序列、最长回文子串等。
算法分析考试题

1. )(n T 给定数组a[0:n-1],试设计一个算法,在最坏情况下用n+[logn]-2次比较找出a[0:n-1] 中的元素的最大值和次大值. (算法分析与设计习题 2.16 ) (分治法)a 、 算法思想用分治法求最大值和次大值首先将问题划分,即将划分成长度相等的两个序列,递归求出左边的最大值次大值,再求出右边的的最大值次大值,比较左右两边,最后得出问题的解。
b 、复杂度分析:把问题划分为左右两种的情况,需要分别递归求解,时间复杂度可如下计算:有递推公式为:T(n)=1 n=1T(n)= 2T(n/2)+1 n>1所以,分治算法的时间复杂度是n+[logn]-2,当n 为奇数时,logn 取上线,当n 为偶数时,logn 取下线。
//不知道为什么会-2!C 、代码实现:#include <stdio.h>int a[100]; void maxcmax(int i,int j,int &max,int &cmax){int lmax,lcmax,rmax,rcmax;int mid;if (i==j){ max=a[i];cmax=a[i];}else if (i==j-1)if (a[i]<a[j]){max=a[j];cmax=a[i];}else{max=a[i];cmax=a[j];}else{mid=(i+j)/2;maxcmax(i,mid,lmax,lcmax);maxcmax(mid+1,j,rmax,rcmax);if(lmax>rmax)if(lcmax>rmax){max=lmax;。
cmax=lcmax;}else{max=lmax;cmax=rmax;}elseif(rcmax>lmax){if(rmax==rcmax){max=rmax;cmax=lmax;}else{max=rmax;cmax=rcmax;}}。
三种方法求解最大子区间和:DP、前缀和、分治

三种⽅法求解最⼤⼦区间和:DP、前缀和、分治题⽬洛⾕:LeetCode:给出⼀个长度为n的序列a,选出其中连续且⾮空的⼀段使得这段和最⼤。
挺经典的⼀道题⽬,下⾯分别介绍O(n) 的 DP 做法、前缀和做法,以及O(n log n) 的分治做法。
DP 做法⽤d i表⽰结尾为位置i的最⼤区间和,则有d i=max(d i−1,0)+a i问题的答案即为max{d i∣i∈[1,n]}。
编写代码时不需要开d数组,⽤变量 last_d 记录d i−1,变量 ans 记录max{d i},并在扫描时动态更新即可。
时间复杂度O(n),空间复杂度O(1)。
核⼼代码如下:maxn = int(2e5 + 5)arr = [0 for _ in range(maxn)] # 从下标 1 开始存# 输⼊过程略……ans = Nonelast_d = 0for i in range(1, n + 1):temp_ans = max(last_d, 0) + arr[i]if ans is None or temp_ans > ans:ans = temp_anslast_d = temp_ansprint(ans)前缀和做法将数列前n项的和记为sum n:sum n=n ∑i=1a i可以⽤前缀和快速求区间和:y∑i=x a i=sum y−sum x−1⽤d i表⽰结尾为位置i的最⼤区间和,则有d i=sum i−min{sum j∣j<i}问题的答案即为max{d i∣i∈[1,n]}。
编写代码时只需要开前缀和数组,⽆需开d数组,⽤变量 cur_min_pre_sum 记录min{sum j},变量 ans 记录max{d i},并动态维护即可。
时间复杂度O(n),空间复杂度O(n)。
核⼼代码如下:maxn = int(2e5 + 5)arr = [0 for _ in range(maxn)] # 原数组,从下标 1 开始存pre_sum = [0 for _ in range(maxn)] # 前缀和数组# 输⼊过程略……# 预处理前缀和for i in range(1, n + 1):pre_sum[i] = pre_sum[i - 1] + arr[i]cur_min_pre_sum = 0ans = Nonefor i in range(1, n + 1):temp_ans = pre_sum[i] - cur_min_pre_sumif ans is None or temp_ans > ans:ans = temp_anscur_min_pre_sum = min(cur_min_pre_sum, pre_sum[i])print(ans)分治做法若有⼀区间 [start,stop),区间中点为mid,其最⼤⼦段和对应的⼦区间为 [i,j),则 [i,j) 只有以下三种情况:[i,j) 完全在左⼦区间 [start,mid) 内;[i,j) 完全在右⼦区间 [mid,stop) 内;[i,j) 横跨中点mid。
分治法求解最大子段和
返回目录
核心代码
int Divide_Conquer(int a[], int left, int right, int *begin, int *end) { int center; int left_left, left_right, leftSum; int right_left, right_right, rightSum; int cross_left, cross_right, crossSum; if (left == right) { *begin = left; *end = right; return a[left]; } center = (left+right)/2; //左边的最大子段和 leftSum = Divide_Conquer(a, left, center, &left_left, &left_right); //右边最大子段和 rightSum = Divide_Conquer(a, center+1, right, &right_left, &right_right); //中间最大子段和 crossSum = find_max_crossing_subarray(a, left, center, right, &cross_left, &cross_right);
返回目录
核心代码
int find_max_crossing_subarray(int a[], int left, int center, int right, int* cross_left, int* cross_right)//寻找跨越中间的最大子段和 { int i; int leftSum; int sum; int rightSum; sum = a[center]; leftSum = a[center]; *cross_left = center; for (i = center-1; i >= left; i--) { sum += a[i]; if (sum > leftSum) { leftSum = sum; *cross_left = i; } }
软件工程专升本测试题含答案
软件工程测试题含答案一、单选题(共30题,每题1分,共30分)1、若一棵二叉树具有8个度为2的结点,5个度为1的结点,则度为0的结点个数是?A、不确定B、6C、11D、9正确答案:D2、$1$TLGHx5co$vq6xM0WG1hYfIV1AZEWgD是什么系统的密码加密值?()A、UNIXB、AIXC、WindowsD、Linux正确答案:D3、在JDBC端抛出“SQL check failed!”的异常信息,原因分析正确的是?A、违规SQL语句被隔离装置拒绝执行B、真实数据库和虚拟式数据库配置错误C、业务系统应用服务器地址检查失败D、webservice自动重连测试SQL语句告警正确答案:A4、array[0]的含义是A、取当前array中第一个元素B、错误操作C、取当前array中最后一个元素D、赋值为0正确答案:A5、()加密算法属于公钥密码算法。
A、IDEAB、RSAC、AESD、DES正确答案:B6、神经网络的基本思想是什么A、将计算变得复杂B、得到更多的参数C、得到更合适的特征D、将计算效率提高正确答案:C7、下列哪种算法更适合做时间序列建模A、贝叶斯算法B、LSTMC、决策树D、CNN正确答案:B8、设某文件经内排序后得到100个初始归并段(初始顺串),若使用多路归并排序算法,且要求三趟归并完成排序,问归并路数最少为A、6B、8C、7D、5正确答案:D9、采用分治法计算最大子段和时间复杂度为A、O(n2)B、O(logn)C、O(n)D、O(nlogn)正确答案:D10、下列个工具包属于集成算法A、pandasB、tensorflowC、xgboostD、numpy正确答案:C11、特征工程的目的是什么A、找到最合适的算法B、加快计算速度C、得到最好的输入数据D、减低模型复杂度正确答案:C12、可变分区存储管理在收回一个空闲区后,空闲区数目可能会()A、减少一个B、保持不变C、增加一个D、上述A、B、C都有可能正确答案:D13、下列哪一项是神经网络的组成部分A、词袋模型B、激活函数C、信息增益D、核函数正确答案:B14、下列哪一项是随机森林的优势A、建模时可动态调整样本权重B、不可并行计算C、基于梯度下降求解速度更快D、输出结果更稳定正确答案:D15、当你感觉到你的Win2003运行速度明显减慢,当打开任务管理器后发现CPU使用率达到了100%,你认为你最有可能受到了()攻击。
【分析】算法分析与设计作业参考答案
【关键字】分析《算法分析与设计》作业参考答案作业一一、名词解释:1.递归算法:直接或间接地调用自身的算法称为递归算法。
2.程序:程序是算法用某种程序设计语言的具体实现。
2、简答题:1.算法需要满足哪些性质?简述之。
算法是若干指令的有穷序列,满足性质:1)输入:有零个或多个外部量作为算法的输入。
2)输出:算法产生至少一个量作为输出。
3)确定性:组成算法的每条指令清晰、无歧义。
4)有限性:算法中每条指令的执行次数有限,执行每条指令的时间也有限。
2.简要分析分治法能解决的问题具有的特征。
分析分治法能解决的问题主要具有如下特征:1)该问题的规模缩小到一定的程度就可以容易地解决;2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;3)利用该问题分解出的子问题的解可以合并为该问题的解;4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
3.简要分析在递归算法中消除递归调用,将递归算法转化为非递归算法的方法。
将递归算法转化为非递归算法的方法主要有:1)采用一个用户定义的栈来模拟系统的递归调用工作栈。
该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。
2)用递推来实现递归函数。
3)通过Cooper变换、反演变换能将一些递归转化为尾递归,从而迭代求出结果。
后两种方法在时空复杂度上均有较大改善,但其适用范围有限。
三、算法编写及算法应用分析题:1.冒泡排序算法的基本运算如下:for i ←1 to n-1 dofor j ←1 to n-i doif a[j]<a[j+1] then交换a[j]、a[j+1];分析该算法的时间复杂性。
解答:排序算法的基本运算步为元素比较,冒泡排序算法的时间复杂性就是求比较次数与n的关系。
1)设比较一次花时间1;2)内循环次数为:n-i次,(i=1,…n),花时间为:3)外循环次数为:n-1,花时间为:2.设计一个分治算法计算一棵二叉树的高度。
最大字段和问题
最⼤字段和问题最⼤⼦段和 -- 分治,dp1.问题描述输⼊⼀个整型数组,数组中的⼀个或连续多个整数组成⼀个⼦数组。
求所有⼦数组的和的最⼤值。
⽰例1:输⼊: nums = [-2,1,-3,4,-1,2,1,-5,4]输出: 6解释: 连续⼦数组 [4,-1,2,1] 的和最⼤,为 6。
2.分析问题2.1 ⽅案1此题很显然可以⽤多层for循环解决, 时间复杂度为O(n^2) .2.2 ⽅案2, 图像压缩问题的变形采⽤dp的思路, 我们把这个数组分成不同的段, **dp[i] 表⽰以nums[i]结尾的那个段的最⼤字段和, 所以就存在nums[i]这个元素是加⼊前⼀段中, 还是⾃成⼀段这就是需要思考的问题, 如果dp[i-1] < 0, 如果nums[i]加⼊前⼀段中, 最⼤字段和为dp[i-1] + nums[i], 这个值必然⼩于nums[i], 因为dp[i-1]是负数, 负数加上⼀个数,必然⽐这个数⼩, 就像是⼀个数减了某个数, 肯定变⼩. 其他情况下只⽤求dp[i-1] + nums[i]和 nums[i] 的最⼤值即可 **通过上⾯的分析, 很容易写出状态转移⽅程// dp初始化dp[0] = nums[0]if(dp[i-1] < 0) dp[i] = nums[i]; // ⾃成⼀段if(dp[i-1] >= 0) dp[i] = Max(dp[i-1] + nums[i], nums[i])简化转移⽅程, dp[i-1]<0时, nums[i] + dp[i-1] 必然是⼩于nums[i]的, 其实也是在求Max(dp[i-1] + nums[i], nums[i]),所以这个题只⽤⼀个⽅程就搞定. 简化了if else的判断, 对程序性能提升也是有帮助的dp[0] = nums[0]dp[i] = Max(dp[i-1] + nums[i], nums[i])这个题很有个很坑的地⽅就是, dp中最后⼀个元素并不是最终要求的结果, 这个我们平时做的题有很⼤的出⼊, dp[i]的含义是以nums[i]结尾的那个段的最⼤字段和, 那么dp中最后⼀个元素表⽰的是以nums中最后⼀个元素结尾的那个段的最⼤字段和, 最⼤的字段和不⼀定以nums中最后⼀个元素结尾,所以要最终要求的⽬标是dp数组中的最⼤值public int maxSubArray(int[] nums) {if(nums == null || nums.length <= 0) throw new IllegalArgumentException();int[] dp = new int[nums.length];dp[0] = nums[0];for(int i = 1; i < nums.length; ++i){dp[i] = Math.max(nums[i], nums[i] + dp[i-1]);}// return dp[nums.length-1]; 神坑int maxValue = Integer.MIN_VALUE;for(int j = 0; j < dp.length; ++j){if(dp[j] > maxValue)maxValue = dp[j];}return maxValue;3. ⽅案3采⽤分治的思路, 我们把数组从中间分开, 最⼤⼦序列的位置就存在以下三种情况最⼤⼦序列在左半边, 采⽤递归解决最⼤⼦序列在右半边, 采⽤递归解决最⼤⼦序列横跨左右半边, 左边的最⼤值加上右边的最⼤值时间复杂度分析T(n) = 2 F(n/2) + n时间复杂度O(nlgn)public int maxSubArray(int[] nums) {if(nums == null || nums.length <= 0) throw new IllegalArgumentException(); return helper(nums, 0, nums.length-1);}private int helper(int [] nums, int start, int end){if(nums == null || nums.length <= 0) throw new IllegalArgumentException(); if(start == end)return nums[start];int middle = start + (end - start) / 2;int leftSums = helper(nums,start, middle);int rightSums = helper(nums,middle+1, end);// 横跨左右两边int leftRightSums;// 左边的最⼤值int lsums = Integer.MIN_VALUE, temp = 0;for(int i = middle; i >= start; i--){temp += nums[i];if(temp > lsums)lsums = temp;}// 右边的最⼤值int rsums = Integer.MIN_VALUE;temp = 0;for(int j = middle+1; j <= end; j++){temp += nums[j];if(temp > rsums) rsums = temp;}leftRightSums = rsums + lsums;return Math.max(Math.max(leftSums, rightSums), leftRightSums);}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if(judge==1){ //自行输入数据
printf("输入%d个整数:",N);
for(i=0;i<N;i++)
scanf("%d",&A[i]);
}
else{
printf("随机产生的%d个整数为:\n",N); //用随机种子随机产生N个0-999的整数
A[i]=rand()%1000;
else
A[i]=(-1)*rand()%1000;
printf("%d\t",A[i]);
}
}
QueryPerformanceCounter(&begin);//记录算法4开始时间
MaxSum=MaxSubsequenceSum(A,N);
QueryPerformanceCounter(&end); //记录算法4终止时间
#include<stdio.h>
#include <time.h>
#include <windows.h>
int MaxSubsequenceSum(int A[],int N);
main()
{
int i,N,*A,MaxSum,judge;
LARGE_INTEGER begin,end,frequency; //代表64位有符号整数,记录程序运行时间
system("pause");
}
int MaxSubsequenceSum(int A[],int N)
{
int ThisSum,MaxSum=0,i,j,k; //对最大值初始化
for(i=0;i<N;i++) //从A[i]开始
for(j=i;j<N;j++){ //以A[j]结束
ThisSum=0;
srand(time(0));
for (i=0;i<N;i++){
if(rand()%2==0) //利用随机数奇偶性的等概率使得正负数约各占一半
A[i]=rand()%1000;
else
A[i]=(-1)*rand()%1000;
printf("%d\t",A[i]);
}
}
QueryPerformanceCounter(&begin);//记录算法3开始时间
分治法求最大子段和问题
共有四种方法:
算法一;
算法二;
算法三、Divide and Conquer
算法四源代码、On-line Algorithm
算法一源代码:
/*Given (possibly negative) integers A1, A2,…, AN, find the maximum value.找最大子段和*/
rights+=a[i];
if(rights>=s2) s2=rights;
}
sum=s1+s2;
if(sum<leftsum) //最大值更新
sum=leftsum;
if(sum<rightsum)
sum=rightsum;
}
return sum;
}
算法四源代码:On-line Algorithm
main()
{
int i,N,*A,MaxSum,judge;
LARGE_INTEGER begin,end,frequency; //代表64位有符号整数,记录程序运行时间
QueryPerformanceFrequency(&frequency);//可以获得当前的处理器的频率
printf("输入整数的个数:");
QueryPerformanceFrequency(&frequency);//可以获得当前的处理器的频率
printf("输入整数的个数:");
scanf("%d",&N);
A=(int *)malloc(N*sizeof(int)); //用数组给数据动态分配空间
printf("自行输入数据请按1,随机产生数据请按2\n");
srand(time(0));
for (i=0;i<N;i++){
if(rand()%2==0) //利用随机数奇偶性的等概率使得正负数约各占一半
A[i]=rand()%1000;
else
A[i]=(-1)*rand()%1000;
printf("%d\t",A[i]);
}
}
QueryPerformanceCounter(&begin);//记录算法1开始时间
for(k=i;k<=j;k++)
ThisSum+=A[k]; //从A[i]到A[j]求和
if(ThisSum>MaxSum)
MaxSum=ThisSum; //更新最大值
}
return MaxSum;
}
算法2源代码:
/*Given (possibly negative) integers A1, A2,…, AN, find the maximum value.找最大子段和*/
printf("\n最大子段和为:%d\n",MaxSum);
printf("算法4运行时间为:%f seconds\n",(double)(end.QuadPart-begin.QuadPart)/frequency.QuadPart);//终止时间-开始时间=算法1运行时间
QueryPerformanceFrequency(&frequency);//可以获得当前的处理器的频率
printf("输入整数的个数:");
scanf("%d",&N);
A=(int *)malloc(N*sizeof(int)); //用数组给数据动态分配空间
printf("自行输入数据请按1,随机产生数据请按2\n");
/*Given (possibly negative) integers A1, A2,…, AN, find the maximum value.找最大子段和*/
#include<stdio.h>
#include <time.h>
#include <windows.h>
int MaxSubsequenceSum(int A[],int N);
MaxSum=MaxSubsequenceSum(A,N);
QueryPerformanceCounter(&end); //记录算法1终止时间
printf("\n最大子段和为:%d\n",MaxSum);
printf("算法1运行时间为:%f seconds\n",(double)(end.QuadPart-begin.QuadPart)/frequency.QuadPart);//终止时间-开始时间=算法1运行时间
#include<stdio.h>
#include <time.h>
#include <windows.h>
int MaxSubsequenceSum(int A[],int N);
main()
{
int i,N,*A,MaxSum,judge;
LARGE_INTEGER begin,end,frequency; //代表64位有符号整数,记录程序运行时间
QueryPerformanceFrequency(&frequency);//可以获得当前的处理器的频率
printf("输入整数的个数:");
scanf("%d",&N);
A=(int *)malloc(N*sizeof(int)); //用数组给数据动态分配空间
printf("自行输入数据请按1,随机产生数据请按2\n");
system("pause");
}
int MaxSubsequenceSum(int A[],int N)
{
int ThisSum,MaxSum=0,i,j; //对最大值初始化
for(i=0;i<N;i++){ //从A[i]开始
ThisSum=0;
for(j=i;j<N;j++){ //以A[j]结束
system("pause");
}
int Divide_Conquer(int a[],int left,int right)//分治算法
{
int sum=0,leftsum=0,rightsum=0,center,i;
if(left==right){
if(a[left]>0)
sum=a[left];
ThisSum+=A[j]; //从A[i]到A[j]求和
if(ThisSum>MaxSum)
MaxSum=ThisSum; //更新最大值
}
}
return MaxSum;
}
算法三源代码:分治法
/*Given (possibly negative) integers A1, A2,…, AN, find the maximum value.找最大子段和*/