使用分治策略递归和非递归和递推算法解决循环赛日程表课程设计报告

合集下载

递归与分治算法心得

递归与分治算法心得

递归与分治算法心得
递归与分治算法是算法设计中常见的两种方法,它们在解决问题时都采用了“分而治之”的思想,将问题分解成更小的子问题,然后通过递归调用或者合并子问题的解来得到原问题的解。

通过我的学习和实践,我深刻认识到了递归与分治算法的重要性和优势。

首先,递归算法可以使问题的描述更加简单明了。

通过将问题转化为自身的子问题,我们可以建立起更为简洁优美的数学模型。

其次,递归算法可以使问题的解决过程更加自然。

在递归过程中,我们可以利用已知的子问题解决同类问题,实现代码的复用和模块化。

此外,递归算法还可以解决一些重要的数学问题,如斐波那契数列和二分查找等。

分治算法则更加注重问题的分解和合并。

它将问题划分成若干个规模相同或相近的子问题,然后将子问题的解合并起来得到原问题的解。

这种方法在解决某些复杂问题时具有很大的优势。

例如,在排序算法中,归并排序采用了分治算法的思想,将待排序的序列分成两个长度相等的子序列,然后递归地对子序列排序,最后将子序列合并成有序序列。

这种算法具有较高的稳定性和灵活性,常常被应用于海量数据的排序任务中。

总之,递归与分治算法是算法设计中不可或缺的两种方法。

在解决问题时,我们应该根据具体情况选择合适的算法,并在实践中不断探索、总结和优化。

只有这样,我们才能更好地应对日益复杂多变的计算机科学挑战。

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表摘要:对于单循环赛的比赛日程安排问题,利用分治算法给出了可读性较好的设计,并分析了各种假设下的时间复杂度。

关键词:分治算法;复杂度;递归;循环赛引言任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。

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

分治法是计算机科学中经常使用的一种算法。

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

1分治法应用条件及一般步骤1.1 分治法的应用条件1.1.1能将n个数据分解成k个不同子集合,且得到的k个子集合是可以独立求解的子问题,其中11&&odd(n/2)) copyodd(n);else copy(n);}void copyodd(int n){int m=n/2;for(int i=0;i=m){a[i][j]=b[i];a[m+i][j]=(b[i]+m)%n;}else a[m+i][j]=a[i][j]+m;}for(j=1;j<m;j++){a[i][m+j]=b[i+j];a[b[i+j]][m+j]=i;}}}分析算法的时间性能:当n/2为奇数时,基本语句的执行次数是:当n/2为偶数时,基本语句的执行次数是:综上,时间复杂度为O(4k )。

2.3 运行结果及分析当输入n为2时,输出:0 11 0在上面n=2时的日程表(二维表)中,左边第一列表示球队编号,第二列表示在某天碰到的对手球队的编号。

推广之,对于n行n列的二维日程表,那么,a[0][0],a[1][0],……,a[n-1][0]表示参加循环赛的n支球队的编号;a[0][1],a[0][2],……,a[0][n-1]表示球队a[0][0]在第1,2,……,n-1天碰到的对手球队编号。

a[i][j](i,j<n)表示编号为a[i][0]的球队在第j日遇到的对手球队的编号。

以下同。

算法设计与分析:递归与分治法-实验报告(总8页)

算法设计与分析:递归与分治法-实验报告(总8页)

算法设计与分析:递归与分治法-实验报告(总8页)实验目的:掌握递归与分治法的基本思想和应用,学会设计和实现递归算法和分治算法,能够分析和评价算法的时间复杂度和空间复杂度。

实验内容:1.递归算法的设计与实现3.算法的时间复杂度和空间复杂度分析实验步骤:1)递归定义:一个函数或过程,在其定义或实现中,直接或间接地调用自身的方法,被成为递归。

递归算法是一种控制结构,它包含了解决问题的基础情境,也包含了递归处理的情境。

2)递归特点:递归算法具有以下特点:①依赖于递归问题的部分解被划分为若干较小的部分。

②问题的规模可以通过递推式递减,最终递归终止。

③当问题的规模足够小时,可以直接求解。

3)递归实现步骤:①确定函数的定义②确定递归终止条件③确定递归调用的过程4)经典实例:斐波那契数列递推式:f(n) = f(n-1) + f(n-2)int fib(int n) {if (n <= 0)return 0;else}5)优化递归算法:避免重复计算例如,上述斐波那契数列的递归算法会重复计算一些中间结果,影响效率。

可以使用动态规划技术,将算法改为非递归形式。

int f1 = 0, f2 = 1;for (int i = 2; i <= n; i++) {f1 = f2;使用循环避免递归,重复计算可以大大减少,提高效率。

1)分治算法的定义:将原问题分解成若干个规模较小且类似的子问题,递归求解子问题,然后合并各子问题得到原问题的解。

2)分治算法流程:②将问题分解成若干个规模较小的子问题。

③递归地解决各子问题。

④将各子问题的解合并成原问题的解。

3)分治算法实例:归并排序归并排序是一种基于分治思想的经典排序算法。

排序流程:②分别对各子数组递归进行归并排序。

③将已经排序好的各子数组合并成最终的排序结果。

实现源代码:void mergeSort(int* arr, int left, int right) {if (left >= right)while (i <= mid && j <= right)temp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];temp[k++] = arr[i++];1) 时间复杂度的概念:指完成算法所需的计算次数或操作次数。

算法设计与分析实验报告

算法设计与分析实验报告

实验一找最大和最小元素与归并分类算法实现(用分治法)一、实验目的1.掌握能用分治法求解的问题应满足的条件;2.加深对分治法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。

二、实验内容1、找最大和最小元素输入n 个数,找出最大和最小数的问题。

2、归并分类将一个含有n个元素的集合,按非降的次序分类(排序)。

三、实验要求(1)用分治法求解问题(2)上机实现所设计的算法;四、实验过程设计(算法设计过程)1、找最大和最小元素采用分治法,将数组不断划分,进行递归。

递归结束的条件为划分到最后若为一个元素则max和min都是这个元素,若为两个取大值赋给max,小值给min。

否则就继续进行划分,找到两个子问题的最大和最小值后,比较这两个最大值和最小值找到解。

2、归并分类使用分治的策略来将一个待排序的数组分成两个子数组,然后递归地对子数组进行排序,最后将排序好的子数组合并成一个有序的数组。

在合并过程中,比较两个子数组的首个元素,将较小的元素放入辅助数组,并指针向后移动,直到将所有元素都合并到辅助数组中。

五、源代码1、找最大和最小元素#include<iostream>using namespace std;void MAXMIN(int num[], int left, int right, int& fmax, int& fmin); int main() {int n;int left=0, right;int fmax, fmin;int num[100];cout<<"请输入数字个数:";cin >> n;right = n-1;cout << "输入数字:";for (int i = 0; i < n; i++) {cin >> num[i];}MAXMIN(num, left, right, fmax, fmin);cout << "最大值为:";cout << fmax << endl;cout << "最小值为:";cout << fmin << endl;return 0;}void MAXMIN(int num[], int left, int right, int& fmax, int& fmin) { int mid;int lmax, lmin;int rmax, rmin;if (left == right) {fmax = num[left];fmin = num[left];}else if (right - left == 1) {if (num[right] > num[left]) {fmax = num[right];fmin = num[left];}else {fmax = num[left];fmin = num[right];}}else {mid = left + (right - left) / 2;MAXMIN(num, left, mid, lmax, lmin);MAXMIN(num, mid+1, right, rmax, rmin);fmax = max(lmax, rmax);fmin = min(lmin, rmin);}}2、归并分类#include<iostream>using namespace std;int num[100];int n;void merge(int left, int mid, int right) { int a[100];int i, j,k,m;i = left;j = mid+1;k = left;while (i <= mid && j <= right) {if (num[i] < num[j]) {a[k] = num[i++];}else {a[k] = num[j++];}k++;}if (i <= mid) {for (m = i; m <= mid; m++) {a[k++] = num[i++];}}else {for (m = j; m <= right; m++) {a[k++] = num[j++];}}for (i = left; i <= right; i++) { num[i] = a[i];}}void mergesort(int left, int right) { int mid;if (left < right) {mid = left + (right - left) / 2;mergesort(left, mid);mergesort(mid + 1, right);merge(left, mid, right);}}int main() {int left=0,right;int i;cout << "请输入数字个数:";cin >> n;right = n - 1;cout << "输入数字:";for (i = 0; i < n; i++) {cin >> num[i];}mergesort(left,right);for (i = 0; i < n; i++) {cout<< num[i];}return 0;}六、运行结果和算法复杂度分析1、找最大和最小元素图1-1 找最大和最小元素结果算法复杂度为O(logn)2、归并分类图1-2 归并分类结果算法复杂度为O(nlogn)实验二背包问题和最小生成树算法实现(用贪心法)一、实验目的1.掌握能用贪心法求解的问题应满足的条件;2.加深对贪心法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表

利用分治法设计循环赛日程表作者:王猛来源:《科技经济市场》2008年第07期摘要:对于单循环赛的比赛日程安排问题,利用分治算法给出了可读性较好的设计,并分析了各种假设下的时间复杂度。

关键词:分治算法;复杂度;递归;循环赛引言任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。

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

分治法是计算机科学中经常使用的一种算法。

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

1分治法应用条件及一般步骤1.1 分治法的应用条件1.1.1能将n个数据分解成k个不同子集合,且得到的k个子集合是可以独立求解的子问题,其中11.1.2分解所得到的子问题与原问题具有相似的结构,便于利用递归或循环机制;1.1.3合并各个子问题的解,就是原问题的解。

1.2 分治法的一般步骤1.2.1分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;1.2.2求解子问题:若子问题规模较小而容易解决则直接解,否则再继续分解为更小的子问题,直到容易解决;1.2.3合并:将已求解的各个子问题的解,合并为原问题的解。

2 循环赛分治算法2.1 问题描述有n支球队参加循环赛,设计一个满足下面要求的比赛日程表:2.1.1每支球队必须与其他n-1支球队各赛一次;2.1.2每支球队一天只能比赛一次;2.1.3当n为偶数时,比赛进行n-1天;当n为奇数时,比赛进行n天。

2.2 算法分析当n=2k (k=1、2、3、4……)时,比较简单。

按照分治的策略,可将所有参赛的选手分为两部分,n=2k 个选手的比赛日程表就可以通过为n/2=2k-1 个选手设计的比赛日程表来决定。

递归地执行这种分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单,只要让这2个选手进行比赛就可以了。

再逐步合并子问题的解即可得到原问题的解。

算法如下:void tourna(int n){if(n==1){a[0][0]=1;return;}tourna(n/2);copy(n);}void copy(int n){int m=n/2;for(int i=0;ifor(int j=0;j{a[i][j+m]=a[i][j]+m;a[i+m][j]=a[i][j+m];a[i+m][j+m]=a[i][j];}基本语句的执行次数是:T(n)=3=O(4k ),所以算法的时间复杂度为O( 4k)。

分治策略算法实验报告

分治策略算法实验报告

分治策略算法实验报告引言分治策略是一种经典的算法设计策略,也是算法设计中最重要的思想之一。

其基本思想是将大问题划分成小的、相互独立的子问题,再将子问题合并求解,最终得到原问题的解。

本实验将通过实际例子,验证分治策略算法的有效性。

实验内容本实验选择两个经典的算法问题进行实现和验证,分别是二分查找和快速排序。

这两个问题在算法领域都有重要的应用价值,也是实践分治算法的好例子。

问题1:二分查找二分查找是一种在有序数组中查找特定元素的算法,其基本思想是将数组分为两部分,然后判断目标值在哪一部分,并且逐步缩小问题的规模。

具体实现如下:pythondef binary_search(arr, target):low = 0high = len(arr) - 1while low <= high:mid = (low + high) 2if arr[mid] == target:return midelif arr[mid] < target:low = mid + 1else:high = mid - 1return -1问题2:快速排序快速排序是一种高效的排序算法,其基本思想是通过一趟划分将待排序序列分割成两个独立的子序列,然后递归地对子序列进行排序,最终得到有序序列。

具体实现如下:pythondef quicksort(arr):if len(arr) <= 1:return arrpivot = arr[len(arr) 2]left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]right = [x for x in arr if x > pivot]return quicksort(left) + middle + quicksort(right)实验结果为了验证分治策略算法的有效性,我们分别对上述两个问题进行了测试。

python循环日程安排问题分治法代码详解

python循环日程安排问题分治法代码详解

python循环日程安排问题分治法代码详解分治法是一种递归式的解决问题的策略,它将一个复杂的问题分解为两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,最终用子问题的解来解决原来的问题。

假设我们要用Python来创建一个日程表,这个日程表在一段时间内(例如一周)循环进行某些活动。

我们可以使用分治法来创建这个日程表。

以下是一个简单的例子,我们将每天的日程分为上午、下午和晚上三个部分,然后为每个部分分配活动。

pythonclass Schedule:def __init__(self, days):self.days = daysself.schedule = {"morning": [],"afternoon": [],"evening": [],}def add_activity(self, day, time, activity):if day not in self.days:self.days.append(day)self.schedule[day] = {"morning": [],"afternoon": [],"evening": [],}time_slot = self.schedule[day][time]if activity not in time_slot:time_slot.append(activity)def print_schedule(self):for day in self.days:print(f"{day}:")print(f" Morning: {self.schedule[day]['morning']}")print(f" Afternoon: {self.schedule[day]['afternoon']}")print(f" Evening: {self.schedule[day]['evening']}\n") 在这个例子中,我们首先创建了一个Schedule类,它有两个属性:一个是days列表,用于存储所有的天数;另一个是schedule字典,它以天数为键,以时间段(morning、afternoon、evening)为值,值是一个列表,用于存储该时间段内的所有活动。

使用分治策略递归和非递归和递推算法解决循环赛日程表课程设计报告

使用分治策略递归和非递归和递推算法解决循环赛日程表课程设计报告

《算法设计与分析》课程设计报告题目:循环赛日程表院(系):信息科学与工程学院专业班级:软工学生姓名:学号:指导教师:2018 年 1 月 8 日至 2018 年 1 月 19 日算法设计与分析课程设计任务书目录1 常用算法 (1)1.1分治算法 (1)基本概念: (1)1.2递推算法 (2)2 问题分析及算法设计 (5)2.1分治策略递归算法的设计 (5)2.2 分治策略非递归算法的设计 (7)2.3 递推策略算法的设计 (8)3 算法实现 (9)3.1分治策略递归算法的实现 (9)3.2 分治策略非递归算法的实现 (10)3.3 递推策略算法的实现 (12)4 测试和分析 (15)4.1分治策略递归算法测试 (15)4.2分治策略递归算法时间复杂度的分析 (16)4.3 分治策略非递归算法测试 (16)4.4分治策略非递归算法时间复杂度的分析 (17)时间复杂度为:O(5^(n-1)) (17)4.5 递推策略算法测试 (17)4.6 递推策略算法时间复杂度的分析 (18)时间复杂度为:O(5^(n-1)) (18)4.7 三种算法的比较 (18)5 总结 (19)参考文献 (20)1 常用算法1.1分治算法基本概念:在计算机科学中,分治法是一种很重要的算法。

字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。

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

例如,对于n个元素的排序问题,当n=1时,不需任何计算。

n=2时,只要作一次比较即可排好序。

n=3时只要作3次比较即可,…。

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

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《算法设计与分析》课程设计报告题目:循环赛日程表院(系):信息科学与工程学院专业班级:软工学生姓名:学号:指导教师:2018 年 1 月 8 日至 2018 年 1 月 19 日算法设计与分析课程设计任务书目录1 常用算法 (1)1.1分治算法 (1)基本概念: (1)1.2递推算法 (2)2 问题分析及算法设计 (5)2.1分治策略递归算法的设计 (5)2.2 分治策略非递归算法的设计 (7)2.3 递推策略算法的设计 (8)3 算法实现 (9)3.1分治策略递归算法的实现 (9)3.2 分治策略非递归算法的实现 (10)3.3 递推策略算法的实现 (12)4 测试和分析 (15)4.1分治策略递归算法测试 (15)4.2分治策略递归算法时间复杂度的分析 (16)4.3 分治策略非递归算法测试 (16)4.4分治策略非递归算法时间复杂度的分析 (17)时间复杂度为:O(5^(n-1)) (17)4.5 递推策略算法测试 (17)4.6 递推策略算法时间复杂度的分析 (18)时间复杂度为:O(5^(n-1)) (18)4.7 三种算法的比较 (18)5 总结 (19)参考文献 (20)1 常用算法1.1分治算法基本概念:在计算机科学中,分治法是一种很重要的算法。

字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。

这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。

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

例如,对于n个元素的排序问题,当n=1时,不需任何计算。

n=2时,只要作一次比较即可排好序。

n=3时只要作3次比较即可,…。

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

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

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

分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。

这种算法设计策略叫做分治法。

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

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

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

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

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

分治法适用的情况:分治法所能解决的问题一般具有以下几个特征:1) 该问题的规模缩小到一定的程度就可以容易地解决2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。

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

1.2递推算法递推算法是一种根据递推关系进行问题求解的方法。

递推关系可以抽象为一个简单的数学模型,即给定一个数的序列a0,a1...,an若存在整数n0,使当n>n0时可以用等号将an与其前面的某些项ai联系起来,这样的式子成为递推公式。

递推算法是一种简单的算法,通过已知条件利用特点的递推关系可以得出中间推论,直至得到问题的最终结果,递推算法分为顺推法和逆推法两种,顺推法则是在不知道初始条件的情况下,从问题的结果除非经递推关系逐步推算出问题的解,这个问题的解也是问题的初始条件。

递归法是从已知条件出发,一步步地递推出未知项,直到问题的解。

递归也是递推的一种,只不过它是对待解问题的递推,知道把一个负责的问题递推为简单的易解问题,然后再一步步返回,从而得到原问题的解。

严格来讲,递归不仅仅是一种问题求解方法,更是一种编程技术,许多算法可以通过递归技术来编程实现。

在计算机科学中,人们把程序直接或间接调用自身的过程称为递归。

过程或函数直接调用自身的递归成为直接递归,间接调用自身的递归称为间接递归。

在问题求解中,采用递归算法有两个重要的好处:一是容易证明算法有两个重要的好处,其次是代码实现简洁,代码编程量少。

不足是程序运行效率较低。

递推算法的基本思想是把一个复杂庞大的计算过程转化为简单过程的多次重复。

该算法利用了计算机速度快和自动化的特点。

而递归法的思想是从已知条件出发,一步步地递推出未知项,直到问题的解。

五种典型的递推关系:1.Fibonacci数列在所有的递推关系中,Fibonacci数列应该是最为大家所熟悉的。

在最基础的程序设计语言Logo语言中,就有很多这类的题目。

而在较为复杂的Basic、Pascal、C语言中,Fibonacci数列类的题目因为解法相对容易一些,逐渐退出了竞赛的舞台。

可是这不等于说Fibonacci数列没有研究价值,恰恰相反,一些此类的题目还是能给我们一定的启发的。

Fibonacci数列的代表问题是由意大利著名数学家Fibonacci于1202年提出的“兔子繁殖问题”(又称“Fibonacci问题”)。

问题的提出:有雌雄一对兔子,假定过两个月便可繁殖雌雄各一的一对小兔子。

问过n个月后共有多少对兔子?解:设满x个月共有兔子Fx对,其中当月新生的兔子数目为Nx对。

第x-1个月留下的兔子数目设为Fx-1对。

则:Fx=Nx+ Fx-1Nx=Fx-2 (即第x-2个月的所有兔子到第x个月都有繁殖能力)∴ Fx=Fx-1+Fx-2 边界条件:F0=0,F1=1由上面的递推关系可依次得到:F2=F1+F0=1,F3=F2+F1=2,F4=F3+F2=3,F5=F4+F3=5,……。

Fabonacci数列常出现在比较简单的组合计数问题中,例如以前的竞赛中出现的“骨牌覆盖”问题。

在优选法中,Fibonacci数列的用处也得到了较好的体现。

2.Hanoi塔问题问题的提出:Hanoi塔由n个大小不同的圆盘和三根木柱a,b,c组成。

开始时,这n个圆盘由大到小依次套在a柱上,如图3-11所示。

要求把a柱上n个圆盘按下述规则移到c柱上:(1)一次只能移一个圆盘;(2)圆盘只能在三个柱上存放;(3)在移动过程中,不允许大盘压小盘。

问将这n个盘子从a柱移动到c柱上,总计需要移动多少个盘次?解:设hn为n个盘子从a柱移到c柱所需移动的盘次。

显然,当n=1时,只需把a 柱上的盘子直接移动到c柱就可以了,故h1=1。

当n=2时,先将a柱上面的小盘子移动到b柱上去;然后将大盘子从a柱移到c 柱;最后,将b柱上的小盘子移到c柱上,共记3个盘次,故h2=3。

以此类推,当a柱上有n(n2)个盘子时,总是先借助c柱把上面的n-1个盘子移动到b柱上,然后把a柱最下面的盘子移动到c柱上;再借助a柱把b柱上的n-1个盘子移动到c柱上;总共移动hn-1+1+hn-1个盘次。

∴hn=2hn-1+1 边界条件:h1=13.平面分割问题问题的提出:设有n条封闭曲线画在平面上,而任何两条封闭曲线恰好相交于两点,且任何三条封闭曲线不相交于同一点,问这些封闭曲线把平面分割成的区域个数。

解:设an为n条封闭曲线把平面分割成的区域个数。

由图3-13可以看出:a2-a1=2;a3-a2=4;a4-a3=6。

从这些式子中可以看出an-an-1=2(n-1)。

当然,上面的式子只是我们通过观察4幅图后得出的结论,它的正确性尚不能保证。

下面不妨让我们来试着证明一下。

当平面上已有n-1条曲线将平面分割成an-1个区域后,第n-1条曲线每与曲线相交一次,就会增加一个区域,因为平面上已有了n-1条封闭曲线,且第n条曲线与已有的每一条闭曲线恰好相交于两点,且不会与任两条曲线交于同一点,故平面上一共增加2(n-1)个区域,加上已有的an-1个区域,一共有an-1+2(n-1)个区域。

所以本题的递推关系是an=an-1+2(n-1),边界条件是a1=1。

4.Catalan数Catalan数首先是由Euler在精确计算对凸n边形的不同的对角三角形剖分的个数问题时得到的,它经常出现在组合计数问题中。

问题的提出:在一个凸n边形中,通过不相交于n边形内部的对角线,把n边形拆分成若干三角形,不同的拆分数目用hn表示,hn即为Catalan数。

例如五边形有如下五种拆分方案(图3-14),故h5=5。

求对于一个任意的凸n边形相应的hn。

5.第二类Stirling数n个有区别的球放到m个相同的盒子中,要求无一空盒,其不同的方案数用S(n,m)表示,称为第二类Stirling数。

根据定义来推导带两个参数的递推关系——第二类Stirling数。

解:设有n个不同的球,分别用b1,b2,……bn表示。

从中取出一个球bn,bn的放法有以下两种:①bn独自占一个盒子;那么剩下的球只能放在m-1个盒子中,方案数为S2(n-1,m-1);②bn与别的球共占一个盒子;那么可以事先将b1,b2,……bn-1这n-1个球放入m个盒子中,然后再将球bn可以放入其中一个盒子中,方案数为mS2(n-1,m)。

综合以上两种情况,可以得出第二类Stirling数定理:【定理】S2(n,m)=mS2(n-1,m)+S2(n-1,m-1) (n>1,m1)边界条件可以由定义2推导出:S2(n,0)=0;S2(n,1)=1;S2(n,n)=1;S2(n,k)=0(k>n)。

2 问题分析及算法设计2.1分治策略递归算法的设计从本问题的具体情况出发,根据分治算法思想,设计出本问题的分治递归算法按分治策略,可将所有选手分成两组。

n个选手的比赛日程表,可以通过n/2个选手的比赛日程表,可以通过n/4个选手设计日程表来决定;……;直到为2个选手的比赛日程表。

这样比赛日程表的设计就变得很简单,这时只要让两个选手互相比赛即可,这样可以形成n/2组2个选手的比赛日程表(如表1、表2)。

然后再反过来在两个选手的日程表上为4个选手设计比赛日程表(如表3)。

然后再类推到8个、16个、……、2k个选手。

对所有运动员的赛程进行安排,并将其存入数组内:由初始化的第一行填充第二行:(填充原则是对角线填充)最后是第三部分的填充1 2 3 4 5 6 7 82 1 43 6 5 8 73 4 1 2 7 8 5 64 3 2 1 8 7 6 55 6 7 8 1 2 3 46 5 87 2 1 4 37 8 5 6 3 4 1 28 7 6 5 4 3 2 1 这样循环,直到填充完毕递归算法解:2.2 分治策略非递归算法的设计分治策略同上。

相关文档
最新文档