分治法(浅谈分治法)
来源:互联网 发布:淘宝客 api 编辑:程序博客网 时间:2024/05/15 07:51
分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。
步骤:
1,划分问题:把问题的实力划分成子问题
2,递归求解:递归解决子问题。
3. 合并问题:合并子问题的解得到原问题的解。
下面介绍一个例子。(帮助理解分治法)
求最大连续和,给出一个长度为n的序列A1,A2,...An,求最大连续和。换句话说,要求找到1<=i<=j<=n,使得Ai+Ai+1+...+Aj最大
分析:
在本例中,“划分”就是把序列分成元素个数尽量相等的两半,“递归求解”就是分别求出完全位于左半或者右半的最佳序列;“合并”就是求出起点位于左半、终点位于右半的最大连续子序列的和,并和子问题的最优解比较。
前两部分没有什么特别之处,关键在于“合并”步骤。既然起点位于左半,终点位于右半,则可以人为地把这样的序列分成两部分,然后独立求解,先寻找最佳起点,然后再寻找最佳终点。
代码如下:
<span style="font-size:24px;">#include"stdio.h"#include"stdlib.h"#include"string.h"#include"algorithm"#include"math.h"using namespace std;//求最大连续和 //时间复杂度 O(nlogn) long long maxsum(int a[],int x,int y) //返回闭合区间【x,y】中最大的连续和 { if(x==y) return a[x]; //只有一个元素直接返回 //int m=(x+y)/2; int m=x+(y-x)/2; //相比上一句,这样写更具有鲁棒性。 //分治的第一步,划分成【x,m】和【m+1,y】 两部分 long long sum_max=max(maxsum(a,x,m),maxsum(a,m+1,y)); //分治法的第二步,递归求解(子问题的最优解) long long L_sum=0,R_sum=0,tem=0; for(int i=m;i>=x;i--) L_sum=max(L_sum,tem+=a[i]); //分治法第三步(1),从分界点开始往左的最大连续和L tem=0; for(int i=m+1;i<=y;i++) R_sum=max(R_sum,tem+=a[i]); //分治法第三步(1),从分界点开始往右的最大连续和R return max(sum_max,L_sum+R_sum); //把子问题的解与 (L和R的和) 比较 } int main(){ int n,*a; scanf("%d",&n); a=(int *)malloc(sizeof(int)*n); for(int i=0;i<n;i++) scanf("%d",&a[i]); printf("%lld\n",maxsum(a,0,n-1)); return 0;} </span>分治法里例子还有许多,比如比较经典的还有: 归并排序、快速排序
1 0
- 分治法(浅谈分治法)
- 幂取模 (分治法)
- (四)分治法
- 分治法(1)
- 分治法(一)
- 分治法(二)
- 分治法
- 分治法
- 分治法
- 分治法
- 分治法
- 分治法
- 分治法
- 分治法
- 分治法
- 分治法
- 分治法
- 分治法
- IRP
- WORDPRESS第二课/WP-ADMIN目录文件
- 第二届蓝桥杯C/C++组第九题 购物(递归)
- 【Redis笔记(六)】 Redis数据结构 - 有序集合zset
- Dijkstra最短路算法
- 分治法(浅谈分治法)
- 重定向操作(C语言)
- WORDPRESS第三课WP-ADMIN/IMAGES和WP-ADMIN/IMPORT目录文件
- java 中==和.equals 区别
- git push出现 REMOTE HOST IDENTIFICATION HAS CHANGED!
- form表单回车自动提交(禁止)
- Spring 的事务处理浅谈
- 二分法求平方根
- linux Kill 多个进程