算法设计与分析 王红梅 第二版 第4章_分治法

合集下载

算法设计及分析(第2版)王红梅胡明习题答案解析

算法设计及分析(第2版)王红梅胡明习题答案解析
else
return 0;
}
intmain()
{
char s1[19]="ababcabccabccacbab";
char s2[7]="abccac";
cout<< BF( s1, s2) <<endl;
return 0;
}
//KMP算法
#include<iostream>
using namespace std;
习题1
1. 图论诞生于七桥问题。出生于瑞士的伟大数学家欧拉(Leonhard Euler,1707—1783)提出并解决了该问题。七桥问题是这样描述的:一个人是否能在一次步行中穿越哥尼斯堡(现在叫加里宁格勒,在波罗的海南岸)城中全部的七座桥后回到起点,且每座桥只经过一次,图1.7是这条河以及河上的两个岛和七座桥的草图。请将该问题的数据模型抽象出来,并判断此问题是否有解。
3.分析以下程序段中基本语句的执行次数是多少,要求列出计算公式。
(1)基本语句2*i<n执行了n/2次
基本语句y = y + i * j执行了2/n次
一共执行次数=n/2+n/2=O(n)
(2)基本语句m+=1执行了(n/2)*n=O(n*n)
4.使用扩展递归技术求解下列递推关系式:
(1) (2)
(1) int T(int n)
++low;
b[high]=b[low];
}
b[low]=b[0];
return low;
}
void qsort(int l[],int low,int high)
{
int prvotloc;

算法设计与分析第四章课件

算法设计与分析第四章课件
各活动的起始时间和 结束时间存储于数组s 和f中且按结束时间的 非减序排列

}
若被检查的活动i的开始时间Si小于最近选择 的活动j的结束时间fi,则不选择活动i,否则 选择活动i加入集合A中。


由于输入的活动以其完成时间的非减序排列, 所以算法每次总是选择具有最早完成时间的相 容活动加入集合A中。直观上,按这种方法选 择相容活动为未安排活动留下尽可能多的时间。 也就是说,该算法的贪心选择的意义是使剩余 的可安排时间段极大化,以便安排尽可能多的 相容活动。 算法的效率极高。当输入的活动已按结束时间 的非减序排列,算法只需θ (n)的时间安排n个 活动,使最多的活动能相容地使用公共资源。 如果所给出的活动未按非减序排列,可以用 θ (nlogn)的时间重排。
贪心算法的基本要素

最优子结构

当一个问题的最优解包含其子问题的最优解 时,称此问题具有最优子结构性质。问题的 最优子结构性质是该问题可用动态规划算法 或贪心算法求解的关键特征。
贪心算法与动态规划算法的差异

贪心算法和动态规划算法都要求问题具 有最优子结构性质,这是两类算法的一 个共同点。但是,对于具有最优子结构 的问题应该选用贪心算法还是动态规划 算法求解?是否能用动态规划算法求解的 问题也能用贪心算法求解?
1 i n
All 0

All 0
因此,(y1,y2,…,yn)是一个满足贪心选择性质的最优解。

然后,证明该问题具有最优子结构性质。

设(x1,x2,…,xn)是最优装载问题的一个满足贪心选择 性质的最优解,则x1=1,(x2,…,xn)是轮船载重为cw1且待装船集装箱为{2,3,…,n}时相应最优装载问 题的一个最优解。

算法设计与分析第二版课后习题解答

算法设计与分析第二版课后习题解答

算法设计与‎分析基础课‎后练习答案‎习题1.14.设计一个计‎算的算法,n是任意正‎整数。

除了赋值和‎比较运算,该算法只能‎用到基本的‎四则运算操‎作。

算法求//输入:一个正整数‎n2//输出:。

step1‎:a=1;step2‎:若a*a<n 转step‎3,否则输出a‎;step3‎:a=a+1转ste‎p 2;5. a.用欧几里德‎算法求gc‎d(31415‎,14142‎)。

b. 用欧几里德‎算法求gc‎d(31415‎,14142‎),比检查mi‎n{m,n}和gcd(m,n)间连续整数‎的算法快多‎少倍?请估算一下‎。

a. gcd(31415‎,14142‎) = gcd(14142‎,3131) = gcd(3131, 1618) =gcd(1618, 1513) = gcd(1513, 105) = gcd(1513, 105) = gcd(105, 43) =gcd(43, 19) = gcd(19, 5) = gcd(5, 4) = gcd(4, 1) = gcd(1,0) = 1.b.有a可知计‎算g cd(31415‎,14142‎)欧几里德算‎法做了11‎次除法。

连续整数检‎测算法在1‎4142每‎次迭代过程‎中或者做了‎一次除法,或者两次除‎法,因此这个算‎法做除法的‎次数鉴于1‎·14142‎和2·14142‎之间,所以欧几里‎德算法比此‎算法快1·14142‎/11 ≈1300 与2·14142‎/11 ≈2600 倍之间。

6.证明等式g‎c d(m,n)=gcd(n,m mod n)对每一对正‎整数m,n都成立.Hint:根据除法的‎定义不难证‎明:●如果d整除‎u和v, 那么d一定‎能整除u±v;●如果d整除‎u,那么d也能‎够整除u的‎任何整数倍‎k u.对于任意一‎对正整数m‎,n,若d能整除‎m和n,那么d一定‎能整除n和‎r=m mod n=m-qn;显然,若d能整除‎n和r,也一定能整‎除m=r+qn和n。

算法设计与分析基础第2版清华出版社ch4分治法-02

算法设计与分析基础第2版清华出版社ch4分治法-02
else if k < A[mid] r=m-1 else l=m+1
return -1
• 折半查找效率分析: • 基本操作:比较 • 最坏情况下,比较次数
C(n)=C( n/2)+1
C(1)=1
设n=2 k ,可解得
C(n)=k+1=log2n+1 • 于是
C(n)∈Θ(log2n)
折半查找举例:
//s是中轴元素/基准点,是数组分区位置的标志 中轴元素如何选?
数组的分区算法:
• 算法 Partition( A[l..r] ) // 输入:子数组A[l..r] // 输出:分裂点/基准点pivot的位置 p ← A[l] i ← l; j ← r+1 repeat repeat i ←i + 1 until A[i] ≥ p repeat j ← j – 1 until A[j] ≤ p swap( A[i], A[j] ) until i ≥ j swap( A[i], A[j] ) swap( A[l], A[j] ) return j
• 其中,f(n)是一个函数,表示将问题分解为
小问题和将结果合并起来所消耗时间(对 于求和的例子来说,a=b=2, f(n)=1)。该 递推式被称为通用分治递推式。
主定理 如果在递推式中f(n)∈⊙(n),其中 d>=0,那么:
⊙(n)
当a<b时
T(n)∈
⊙(nlog n) 当a=b时
⊙(n) 当a> b时
• 有了上面的中序遍历的过程,前序遍历也是类似 的。在遍历以前首先确定遍历的树是否为空,如 果为空,则直接返回;否则前序遍历的算法步骤 如下: (1)访问输出根结点V的值; (2)对左子树L执行前序遍历算法。 (3)对右子树R执行前序遍历算法。

算法分析实验指导书(王红梅)

算法分析实验指导书(王红梅)

《算法设计与分析》实验指导书计算机科学与技术学院石少俭实验一分治法1、实验目的(1)掌握设计有效算法的分治策略。

(2)通过快速排序学习分治策略设计技巧2、实验要求(1)熟练掌握分治法的基本思想及其应用实现。

(2)理解所给出的算法,并对其加以改进。

3、分治法的介绍任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。

问题的规模越小,越容易直接求解,解题所需的计算时间也越少。

而当n较大时,问题就不那么容易处理了。

要想直接解决一个规模较大的问题,有时是相当困难的。

分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

如果原问题可分割成k个子问题,1<k≤n ,且这些子问题都可解,并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。

由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。

在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。

这自然导致递归过程的产生。

分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。

分治法的适用条件(1)该问题的规模缩小到一定的程度就可以容易地解决;(2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。

(3)利用该问题分解出的子问题的解可以合并为该问题的解;(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。

上述的第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是应用分治法的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑贪心法或动态规划法。

第四条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。

算法设计与分析(第2版)-王红梅-胡明-习题答案(1)

算法设计与分析(第2版)-王红梅-胡明-习题答案(1)

算法设计与分析(第2版)-王红梅-胡明-习题答案习题11. 图论诞生于七桥问题。

出生于瑞士的伟大数学家欧拉(Leonhard Euler ,1707—1783)提出并解决了该问题。

七桥问题是这样描述的:一个人是否能在一次步行中穿越哥尼斯堡(现在叫加里宁格勒,在波罗的海南岸)城中全部的七座桥后回到起点,且每座桥只经过一次,图 1.7是这条河以及河上的两个岛和七座桥的草图。

请将该问题的数据模型抽象出来,并判断此问题是否有解。

七桥问题属于一笔画问题。

输入:一个起点输出:相同的点1, 一次步行2, 经过七座桥,且每次只经历过一次3, 回到起点该问题无解:能一笔画的图形只有两类:一类是所有的点都是偶点。

另一类是只有二个奇点的图形。

2.在欧几里德提出的欧几里德算法中(即最初的欧几里德算法)用的不是除法而是减法。

请用伪代码描述这个版本的欧几里德算法1.r=m-n2.循环直到r=02.1 m=n图1.7 七桥问题2.2 n=r2.3 r=m-n3 输出m3.设计算法求数组中相差最小的两个元素(称为最接近数)的差。

要求分别给出伪代码和C++描述。

//采用分治法//对数组先进行快速排序//在依次比较相邻的差#include <iostream>using namespace std;int partions(int b[],int low,int high){int prvotkey=b[low];b[0]=b[low];while (low<high){while (low<high&&b[high]>=prvotkey)--high;b[low]=b[high];while (low<high&&b[low]<=prvotkey)++low;b[high]=b[low];}b[low]=b[0];return low;}void qsort(int l[],int low,int high){int prvotloc;if(low<high){prvotloc=partions(l,low,high); //将第一次排序的结果作为枢轴qsort(l,low,prvotloc-1); //递归调用排序由low 到prvotloc-1qsort(l,prvotloc+1,high); //递归调用排序由 prvotloc+1到 high}}void quicksort(int l[],int n){qsort(l,1,n); //第一个作为枢轴,从第一个排到第n个}int main(){int a[11]={0,2,32,43,23,45,36,57,14,27,39};int value=0;//将最小差的值赋值给valuefor (int b=1;b<11;b++)cout<<a[b]<<' ';cout<<endl;quicksort(a,11);for(int i=0;i!=9;++i){if( (a[i+1]-a[i])<=(a[i+2]-a[i+1]) )value=a[i+1]-a[i];elsevalue=a[i+2]-a[i+1];}cout<<value<<endl;return 0;}4.设数组a[n]中的元素均不相等,设计算法找出a[n]中一个既不是最大也不是最小的元素,并说明最坏情况下的比较次数。

算法设计与分析王红梅第二版动态规划详解演示文稿

算法设计与分析王红梅第二版动态规划详解演示文稿

2022/3/2
Chapter 6 Dynamic Programming
26
第26页,共110页。
多段图的最短路径问题
多段图的决策过程:
多段图的边(u, v),用cuv 表边的权值,从源点s到终点t的最短路 径记为d(s, t),则从源点0到终点9的最短路径d(0, 9)由下式确定 :
d(0, 9)=min{c01+d(1, 9), c02+d(2, 9), c03+d(3, 9)}
2022/3/2
Chapter 6 Dynamic Programming
10
第10页,共110页。
动态规划法的设计思想
动态规划法的求解过程 原问题
子问题1
子问题2 ……
子问题n
2022/3/2
填表 原问题的解
Chapter 6 Dynamic Programming
11
第11页,共110页。
动态规划法的设计思想
Page 15
第6章 动态规划法
2022/3/2
第15页,共110页。
数塔问题——想法
[想法]从顶层出 发下一层选择 取决于两个4层 数塔的最大数 值和。
8 12 15 3 96 8 10 5 12 16 4 18 10 9
Page 16
第6章 动态规划法
2022/3/2
第16页,共110页。
数塔问题——想法
求解初始子问题:底层的每个数字可看作1层数塔,则最大数值和就是其自身; 再求解下一阶段的子问题:第4层的决策是在底层决策的基础上进行求解,可以看作4 个2层数塔,对每个数塔进行求解; 再求解下一阶段的子问题:第3层的决策是在第4层决策的基础上进行求解,可以看作3个 2层的数塔,对每个数塔进行求解;

算法设计与分析-总结0

算法设计与分析-总结0

这本书是《算法设计与分析》王红梅编著一共有以下12章,我们学了1、3、4、5、6、7、8、9分别是“绪论、蛮力法、分治法、减治法、动态规划法、贪心法、回溯法、分治限界法第1章绪论考点:1、算法的5个重要特性。

(P3)答:输入、输出、有穷性、确定性、可行性2、描述算法的四种方法分别是什么,有什么优缺点。

(P4)答:1. 自然语言优点:容易理解;缺点:容易出现二义性,并且算法都很冗长。

2. 流程图优点:直观易懂;缺点:严密性不如程序语言,灵活性不如自然语言。

3. 程序设计语言优点:用程序语言描述的算法能由计算机直接执行;缺点:抽象性差,是算法设计者拘泥于描述算法的具体细节,忽略了“好”算法和正确逻辑的重要性,此外,还要求算法设计者掌握程序设计语言及其编程技巧。

伪代码优点:表达能力强,抽象性强,容易理解3、了解非递归算法的时间复杂性分析。

(P13)要点:对非递归算法时间复杂性的分析,关键是建立一个代表算法运行时间的求和表达式,然后用渐进符号表示这个求和表达式。

非递归算法分析的一般步骤是:(1)决定用哪个(或哪些)参数作为算法问题规模的度量。

(2)找出算法的基本语句。

(3)检查基本语句的执行次数是否只依赖问题规模。

(4)建立基本语句执行次数的求和表达式。

(5)用渐进符号表示这个求和表达式。

[例1.4]:求数组最小值算法int ArrayMin(int a[ ], int n){min=a[0];for (i=1; i<n; i++)if (a[i]<min) min=a[i];return min;}问题规模:n基本语句:a[i]<minT(n)= n-1=O(n)4、掌握扩展递归技术和通用分治递推式的使用。

(P15)扩展递归技术:通用分支递归式:5、习题1-4,习题1-7设计算法求数组中相差最小的两个元素(称为最接近数)的差。

要求给出伪代码描述,并用一组例子进行跟踪验证,写出验证过程。

《算法设计与分析教学资料》第4章-PPT课件

《算法设计与分析教学资料》第4章-PPT课件
6
贪心算法的引入--找币问题
一种更简单可行的方法:
1. 先取2.5 2枚
价值2.5+2.5=5.0
余6.3-5=1.3
2. 再取1.0 1枚
价值1.0
余1.3-1=0.3
3. 不取0.5 0枚
因为0.5>0.3
4. 再取0.1 3枚
价值0.1×3=0.3
余0.3-0.3=0
5. 找零完毕。
6. 得最优解X={ 2, 1, 0, 3 } ,共需最少的硬币数6枚。
方法总结:在不超余额的前提下,每次都找最大面 值的硬币。这种找币的方法叫做贪心算法。
思考:有没有可能不是最好的方法?
7
贪心算法—描述
顾名思义,贪心算法总是作出在当前看来最好的 选择。也就是说贪心算法并不从整体最优考虑, 它所作出的选择只是在某种意义上的局部最优选 择。
当然,希望贪心算法得到的最终结果也是整体最 优的。虽然贪心算法不能对所有问题都得到整体 最优解,但对许多问题它能产生整体最优解。如 单源最短路经问题,最小生成树问题等。
新学期来临,为迎接新生,各院系都要举办迎新晚 会。时间将近,各院系在申请使用学院礼堂进行彩 排。为了提高礼堂使用率,决定白天不间断的开放, 各院系可以上报各自使用的时间区间(开始时间以 及终止时间,时间长短不限),由礼堂管理人员安 排尽可能多的院系在同一天里彩排。
请根据以下时间段尽可能多安排几个院系: [8:00,10:30), [9:00,11:30), [7:00,11:00), [11:30-14:00), [12:00,13:30) , [13:00,15:30), [15:00,16:00), [14:30,16:00), [16:00,18:00)

算法设计与分析(第2版) 王红梅 胡明 习题参考答案

算法设计与分析(第2版) 王红梅 胡明 习题参考答案
#include<iostream>
usingnamespacestd;
intmain()
{
longdoubleresult=1;
doublej=1;
for(inti=1;i<=64;++i)
{
j=j*2;
result+=j;
j++;
}
cout<<result<<endl;
return0;
}
习题3
1.假设在文本"ababcabccabccacbab"中查找模式"abccac",写出分别采用BF算法和KMP算法的串匹配过
else
value=a[i+2]-a[i+1];
}
cout<<value<<endl;
return0;
}
4.设数组a[n]中的元素均不相等,设计算法找出a[n]中一个既不是最大也不是最小的元素,并说明最坏情况下的比较次数。要求分别给出伪代码和C++描述。
#include<iostream>
usingnamespacestd;
{
if(n==1)
return4;
elseif(n>1)
return3*T(n-1);
}
(2)
intT(intn)
{
if(n==1)
return1;
elseif(n>1)
return2*T(n/3)+n;
}
5.求下列问题的平凡下界,并指出其下界是否紧密。
(1)求数组中的最大元素;
(2)判断邻接矩阵表示的无向图是不是完全图;

计算机算法设计与分析方法与应用复习

计算机算法设计与分析方法与应用复习

计算机算法设计与分析方法与应用复习计算机算法是计算机科学中一项重要的基础知识,它涉及到了计算机程序的设计与实现。

在计算机算法设计与分析方法与应用的学习中,我们需要掌握各种不同的算法以及它们的应用场景和分析方法。

本篇文章将对计算机算法设计与分析方法与应用进行复习,包括以下几个方面的内容:分治法、动态规划、贪婪算法、回溯法、图算法等。

一、分治法分治法是一种将问题分解成更小规模子问题的方法,然后将子问题的解组合起来得到原问题的解。

在分治法中,我们需要考虑如何将问题划分成子问题、如何求解子问题和如何将子问题的解合并成原问题的解。

分治法常用于解决一些复杂的计算问题,例如快速排序、合并排序等。

快速排序是一种常用的排序算法,它的基本思想是通过选取一个基准元素,将待排序的序列划分成两部分,一部分小于基准元素,一部分大于基准元素。

然后对两部分分别进行递归排序,最终得到有序序列。

快速排序的时间复杂度为O(nlogn),是一种效率较高的排序算法。

其具体实现如下:```void quickSort(int arr[], int low, int high){if (low < high){int i = low, j = high, base = arr[low];while (i < j){while (i < j && arr[j] >= base){ j--;}if (i < j){arr[i] = arr[j];i++;}while (i < j && arr[i] <= base){ i++;}if (i < j){arr[j] = arr[i];j--;}}arr[i] = base;quickSort(arr, low, i - 1);quickSort(arr, i + 1, high);}}```二、动态规划动态规划是一种通过把问题分解成相互重叠的子问题,并保存子问题的解来求解原问题的方法。

算法设计与分析(第2版)

算法设计与分析(第2版)

2016年2月1日,该教材由清华大学出版社出版。
内容简介
该教材为计算机类专业核心课程“算法设计与分析”教材,全书以算法设计技术和分析方法为主线来组织各 知识单元。全书共10章,第1章是基础知识,介绍和算法设计与分析有关的基本概念、符号和数学知识;第2~5章 分别阐述分治策略、动态规划、贪心法、回溯与分支限界等算法设计技术;第6章介绍算法分析与问题的计算复杂 度;第7章是NP完全性理论;第8章是近似算法;第9章是随机算法;第10章介绍处理难解问题的策略。
该教材的主要特点是:
作者简介
屈婉玲,女,北京大学信息科学技术学院及软件与微电子学院教授、博士生导师。主讲算法分析与复杂性理 论、算法分析与设计等研究生必修课。研究方向为算法设计与分析、软件形式化方法。
刘田,博士,北京大学信息科学技术学院副教授。主要研究方向为算法分析与计算复杂性理论。长期主讲 “集合论与图论”、“理论计算机科学基础”等课程,2006年和2013年先后两次获得了北京大学教学优秀奖。
算法设计与分析(第2版)
20xx年清华大学出版社出版的图书
01 成书过程
03 教材目录 05 教材特色
目录
02 内容简介设计与分析(第2版)》是由屈婉玲、刘田、张立昂、王捍贫编著,2016年清华大学出版社出版的21 世纪大学本科计算机专业系列教材、普通高等教育“十一五”国家级规划教材。该教材适合作为大学计算机科学 与技术、软件工程、信息安全、信息与计算科学等专业本科生和研究生的教学用书,也可以作为从事实际问题求 解的算法设计与分析工作的科技人员的参考。
该教材为计算机类专业核心课程“算法设计与分析”教材,全书以算法设计技术和分析方法为主线来组织各 知识单元,主要内容包括基础知识、分治策略、动态规划、贪心法等。

算法设计与分析(第2版)-王红梅-胡明-习题答案(1)

算法设计与分析(第2版)-王红梅-胡明-习题答案(1)

算法设计与分析(第2版)-王红梅-胡明-习题答案习题11. 图论诞生于七桥问题。

出生于瑞士的伟大数学家欧拉(Leonhard Euler ,1707—1783)提出并解决了该问题。

七桥问题是这样描述的:一个人是否能在一次步行中穿越哥尼斯堡(现在叫加里宁格勒,在波罗的海南岸)城中全部的七座桥后回到起点,且每座桥只经过一次,图 1.7是这条河以及河上的两个岛和七座桥的草图。

请将该问题的数据模型抽象出来,并判断此问题是否有解。

七桥问题属于一笔画问题。

输入:一个起点输出:相同的点1, 一次步行2, 经过七座桥,且每次只经历过一次3, 回到起点该问题无解:能一笔画的图形只有两类:一类是所有的点都是偶点。

另一类是只有二个奇点的图形。

2.在欧几里德提出的欧几里德算法中(即最初的欧几里德算法)用的不是除法而是减法。

请用伪代码描述这个版本的欧几里德算法1.r=m-n2.循环直到r=02.1 m=n图1.7 七桥问题2.2 n=r2.3 r=m-n3 输出m3.设计算法求数组中相差最小的两个元素(称为最接近数)的差。

要求分别给出伪代码和C++描述。

//采用分治法//对数组先进行快速排序//在依次比较相邻的差#include <iostream>using namespace std;int partions(int b[],int low,int high){int prvotkey=b[low];b[0]=b[low];while (low<high){while (low<high&&b[high]>=prvotkey)--high;b[low]=b[high];while (low<high&&b[low]<=prvotkey)++low;b[high]=b[low];}b[low]=b[0];return low;}void qsort(int l[],int low,int high){int prvotloc;if(low<high){prvotloc=partions(l,low,high); //将第一次排序的结果作为枢轴qsort(l,low,prvotloc-1); //递归调用排序由low 到prvotloc-1qsort(l,prvotloc+1,high); //递归调用排序由 prvotloc+1到 high}}void quicksort(int l[],int n){qsort(l,1,n); //第一个作为枢轴,从第一个排到第n个}int main(){int a[11]={0,2,32,43,23,45,36,57,14,27,39};int value=0;//将最小差的值赋值给valuefor (int b=1;b<11;b++)cout<<a[b]<<' ';cout<<endl;quicksort(a,11);for(int i=0;i!=9;++i){if( (a[i+1]-a[i])<=(a[i+2]-a[i+1]) )value=a[i+1]-a[i];elsevalue=a[i+2]-a[i+1];}cout<<value<<endl;return 0;}4.设数组a[n]中的元素均不相等,设计算法找出a[n]中一个既不是最大也不是最小的元素,并说明最坏情况下的比较次数。

算法设计与分析 王红梅 第二版 第4章_分治法

算法设计与分析 王红梅 第二版 第4章_分治法

i=s; j=m+1; k=s; i j while (i<=m && j<=t) r[s],…,r[m] r[m+1],…,r[t] { if (r[i]<=r[j]) r1[k++]=r[i++]; //取r[i]和r[j]中较小者放入r1[k] else r1[k++]=r[j++]; } k r1[s],…,r1[m],r1[m+1],…,r1[t] if (i<=m) while (i<=m) //若第一个子序列没处理完,则进行收尾处理 r1[k++]=r[i++]; else while (j<=t) //若第二个子序列没处理完,则进行收尾处理 r1[k++]=r[j++]; }
1. Data[i][j]=number; number++; j--;
8. 递归调用函数Full在size-2阶方阵中左上角begin+1处从数字 number开始填数
2015-5-2
Divide and Conquer Method
14
数字旋转方阵
[算法分析]填写n阶方阵,四个区域由4个循环实现,每个循环 均执行n-1,然后执行递归调用,填写n-2阶方阵。递推式:
32 31
分解问题
求解每个子问题
3
3 9 合并子问题的解
不是所有的分治法都比简单的蛮力法更有效。
概 述
4.1.1 分治法的设计思想 4.1.2 一个简单的例子——数字旋转方阵
2015-5-2
Divide and Conquer Method

《算法设计与分析》课程实验报告 (分治法(三))

《算法设计与分析》课程实验报告 (分治法(三))

《算法设计与分析》课程实验报告实验序号:04实验项目名称:实验4 分治法(三)一、实验题目1.邮局选址问题问题描述:在一个按照东西和南北方向划分成规整街区的城市里,n个居民点散乱地分布在不同的街区中。

用x 坐标表示东西向,用y坐标表示南北向。

各居民点的位置可以由坐标(x,y)表示。

街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值∣x1−x2∣+∣y1−y2∣度量。

居民们希望在城市中选择建立邮局的最佳位置,使n个居民点到邮局的距离总和最小。

编程任务:给定n 个居民点的位置,编程计算邮局的最佳位置。

2.最大子数组问题问题描述:对给定数组A,寻找A的和最大的非空连续子数组。

3.寻找近似中值问题描述:设A是n个数的序列,如果A中的元素x满足以下条件:小于x的数的个数≥n/4,且大于x的数的个数≥n/4 ,则称x为A的近似中值。

设计算法求出A的一个近似中值。

如果A中不存在近似中值,输出false,否则输出找到的一个近似中值4.循环赛日程表问题描述:设有n=2^k个运动员要进行网球循环赛。

现要设计一个满足以下要求的比赛日程表:每个选手必须与其他n-1个选手各赛一次,每个选手一天只能赛一次,循环赛一共进行n-1天。

二、实验目的(1)进一步理解分治法解决问题的思想及步骤(2)体会分治法解决问题时递归及迭代两种不同程序实现的应用情况之差异(3)熟练掌握分治法的自底向上填表实现(4)将分治法灵活于具体实际问题的解决过程中,重点体会大问题如何分解为子问题及每一个大问题涉及哪些子问题及子问题的表示。

三、实验要求(1)写清算法的设计思想。

(2)用递归或者迭代方法实现你的算法,并分析两种实现的优缺点。

(3)根据你的数据结构设计测试数据,并记录实验结果。

(4)请给出你所设计算法的时间复杂度的分析,如果是递归算法,请写清楚算法执行时间的递推式。

四、实验过程(算法设计思想、源码)1.邮局选址问题(1)算法设计思想根据题目要求,街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值∣x1−x2∣+∣y1−y2∣度量。

《算法设计与分析》课件第4章

《算法设计与分析》课件第4章
由此可得,如果我们将活动的完成时间排成升序,那么
子问题空间就是从Sij中选择最大相互相容活动子集,0≤i,j ≤n+1,其他的Sij为空。为了搞清楚活动选择问题的子结构, 考虑某些非空子集Sij(有时称做子集,有时称做子问题,读 者可从上下文看出)。假定Sij的一个解包括活动ak,则有 fi≤sk<fk≤sj。活动ak产生两个子问题Sik和Skj。Sik表示活动ai完 成之后,活动ak开始之前的那些活动集。Skj表示活动ak
的相容活动集合。假定集合S={a1, a2,…, an}中含有n个希望 使用某一资源的活动,这样的资源有教室、某一设备等,它
们一次只能由一个活动使用。每个活动ai有开始时间(start time)si和完成时间(finish time)fi,其中,0≤si<fi<∞。如果某 个活动ai被选中使用资源,则该活动在半开区间(si,fi]这 段时间占据资源。如果活动ai和aj在时间区间(si,fi]和(sj, fj]上不重叠,则称它们是相容的(compatible),即如果si≥fj 或者sj≥fi,活动ai和aj是相容的。活动选择问题是选择最大的 相容活动集合。
i 1
述假设,可以推得yk<xk。以下首先证明这一点,分三种情
况讨论:
(1) 若k<j,则xk=1。又yk≠xk,从而yk<xk。
(2) 若k=j,对于1≤i<nj,有xi=yi=1;而对于nj<i≤n,有xi=0。
若yk>xk,显然有
wi y,i 因W为
wi y与i y是W可
行解矛盾。若yk=xk,与假i1设yk≠xk矛盾,因此,i1yk<xk。
所选活动的完成时间随着时间严格递增。我们只需按照完成
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本章要点
4.1 概 述 4.2 排序问题中的分治法 4.3 组合问题中的分治法 4.4 几何问题中的分治法 阅读材料 递归函数的执行过程
2015-5-2
Divide and Conquer Method
16
排序问题中的分治法
4.2.1 4.2.2
归并排序 快速排序
2015-5-2
Divide and Conquer Method
5
概述-分治法思想
启发式规则:
1. 平衡子问题:最好使子问题的规模大致相同。也就是将一 个问题划分成大小相等的k个子问题(通常k=2、4,…),这 种使子问题规模大致相等的做法是出自一种平衡(Balancing) 子问题的思想,它几乎总是比子问题规模不等的做法要好。 2. 独立子问题:各子问题之间相互独立,这涉及到分治法的 效率,如果各子问题不是独立的,则分治法需要重复地解公 共的子问题。
当n=0时 0 当n=1时 T(n) = 1 T(n-2)+4(n-1) 当n>1时
设n为偶数,用扩展递归技术解此递推式,得 T(n)=T(n-2)+4(n-1)=T(n-4)+4(n-3)+4(n-1)
=T(0)+…+4(n-5)+4(n-3)+4(n-1)=O(n2)
2015-5-2 Divide and Conquer Method 15
原问题划分成k个较小规模的子问题,对这k个子问题分别求 解。如果子问题的规模仍然不够小,则再将每个子问题划分
为k个规模更小的子问题,如此分解下去,直到问题规模足够
小,很容易求出其解为止,再将子问题的解合并为一个更大 规模的问题的解,自底向上逐步求出原问题的解。
2015-5-2
Divide and Conquer Method
2015-5-2 Divide and Conquer Method 21
4.2.1 归并排序
算法4.4——合并有序子序列 void Merge(int r[ ], int r1[ ], int s, int m, int t)
{ // i,j分别指向两个待合并的有序子序列,k指向最终有序序列的当前记录
2015-5-2
Divide and Conquer Method
8
概述-分治法的求解过程
分治法的一般过程
1 DivideConquer(P) //求解规模为n的问题P 2 { 3 if (P的规模足够小) 直接求解P; 分解为k个子问题P1, P2, …, Pk; 4 for (i=1;i<=k;i++) 5 yi=DivideConquer(P); //解各子问题,通常采用递归 6 return Merge (y1, y2, …, yk ); //将各子问题的解合并为原问题的解 7 }
2015-5-2
Divide and Conquer Method
9
例:计算an,应用分治技术得到如下计算方法:
a
时间性能 O(nlog2n) 而蛮力法的 时间性能为 O(n)
n
= n a
a n 2 * a
34
2
如果 n = 1 如果 n > 1
32 31 31 3 9 81 31 3
2015-5-2 Divide and Conquer Method 25
2015-5-2
Divide and Conquer Method
23
4.2.2 快速排序
快速排序的分治策略
( 1 )划分:选定一个记录作为轴值,以轴值为基准将整个序 列划分为两个子序列r1 … ri-1和ri+1 … rn,前一个子序列中记录 的值均小于或等于轴值,后一个子序列中记录的值均大于或等 于轴值; [ r1 … … ri-1 ] ri [ ri+1 … … rn ] (2)求解子问题:分别对 划分后的每一个子序列递归 处理; 均 ≤ri 轴值 均 ≥ri (3)合并:由于对子序列 位于最终位置 r1 … ri-1和ri+1 … rn的排序是 就地进行的,所以合并不需 要执行任何操作。
2015-5-2
Divide and Conquer Method
2
学习目标
教学重点 教学难点 教学内容 及目标 分治法的设计思想,各种经典问题的分治思想 几何问题的分治算法 知识点 了解 教学要求 理解 掌握 熟练掌 握 √ √ √ √ √
分治法设计思想
归并排序和快速排序 最大子段和问题 棋盘覆盖问题 最近对问题 凸包问题
Divide and Conquer Method
19
4.2.1 归并排序
[想法] 首先将序列划分为两个子序列,如子序列长度为 1, 则划分结束,否则继续执行划分,结果将具有 n个待排序的 记录序列划分为n个长度为1的有序子序列;然后两两合并, 得到n/2个长度为2的有序子序列,再进行两两合并…直到得 到一个长度为n的有序序列。
2015-5-2
Divide and Conquer Method
20
4.2.1 归并排序
算法4.3——归并排序 void MergeSort(int r[ ], int r1[ ], int s, int t) //r[ ]—原序列数组,r1[ ]—归并后序列数组 { if (s= =t) r1[s]=r[s]; r[s],…,r[m] r[m+1],…,r[t] else { m=(s+t)/2; Mergesort(r, r1, s, m); //归并排序前半个子序列 Mergesort(r, r1, m+1, t); //归并排序后半个子序列 Merge(r1, r, s, m, t); //合并两个已排序的子序列 } }
32 31
分解问题
求解每个子问题
3
3 9 合并子问题的解
不是所有的分治法都比简单的蛮力法更有效。
概 述
4.1.1 分治法的设计思想 4.1.2 一个简单的例子——数字旋转方阵
2015-5-2
Divide and Conquer Method
11
数字旋转方阵
[问题] 输出如图4.3(a)所示N*N(1≤N≤10)的数字旋转方阵 [思路]用二维数组表示方阵,从外层向里层填数,如图(b)所示, 将每一层的填数过程分为ABCD四个区域。每填一层size减2, 终止条件是size≤1。
2015-5-2
Divide and Conquer Method
12
数字旋转方阵
算法4.1:数字旋转方阵Full 输入:当前层左上角要填的数字number,左上角的坐标begin, 方阵的阶数size
输出:数字旋转方阵
1. 如果size=0,则算法结束; 2. 如果size=1,则data[begin][begin]=number,算法结束; 3. 初始化行、列下标i=begin,j=begin; 4. 重复下述操作size-1次,填写区域A 1. Data[i][j]=number; number++; i++;
2015-5-2 Divide and Conquer Method 18
4.2.1 归并排序
r1 … … rn/2 rn/2+1 … … rn 划分
r‘1<… …<r’n/2 r’n/2+1<… …<r’n r''1<……<r''n/2<r''n/2+1 <……<r ''n
递归处理
合并解
2015-5-2
2015-5-2 Divide and Conquer Method 13
数字旋转方阵
5. 重复下述操作size-1次,填写区域B 1. Data[i][j]=number; number++; j++; 6. 重复下述操作size-1次,填写区域C 1. Data[i][j]=number; number++; i--; 7. 重复下述操作size-1次,填写区域D
1. Data[i][j]=number; number++; j--;
8. 递归调用函数Full在size-2阶方阵中左上角begin+1处从数字 number开始填数
2015-5-2
Divide and Conquer Method
14
数字旋转方阵
[算法分析]填写n阶方阵,四个区域由4个循环实现,每个循环 均执行n-1,然后执行递归调用,填写n-2阶方阵。递推式:
2015-5-2 Divide and Conquer Method 24
4.2.2 快速排序
以第一个记录为轴值(可随机),对待排序序列进行划分的过程: ( 1 )初始化:取第一个记录作为基准,设置两个参数 i , j 分别 用来指示将要与基准记录进行比较的左侧记录位置和右侧记录位 置,也就是本次划分的区间; (2)右侧扫描过程:将基准记录与j指向的记录进行比较,如果 j指向记录的关键码大,则j--,即前移一个记录位置。重复右侧扫 描过程,直到右侧的记录小(即反序),若i<j,则将基准记录 与j指向的记录进行交换; (3)左侧扫描过程:将基准记录与i指向的记录进行比较,如果i 指向记录的关键码小,则 i++,即后移一个记录位置。重复左侧 扫描过程,直到左侧的记录大(即反序),若i<j,则将基准记 录与i指向的记录交换;

2015-5-2
Divide and Conquer Method
3
概 述
4.1.1 分治法的设计思想 4.1.2 分治法的求解过程
2015-5-2
Divide and Conquer Method
相关文档
最新文档