2016年算法分析与设计练习题
一、 算法时间复杂度分析 1、渐进符号
几个常见的渐进符号: 渐近上界符号O 渐近下界符号Ω 紧渐近界符号Θ 2、基本效率类型
常数、对数、线性、n-log-n、平方、立方、指数、阶乘 运行时间为n的多项式的算法称为好算法 算法设计的几个原则:
如果一个程序只用一、两次,那么书写和调试所用的时间比运行程序时间大得多,因而算法应易于理解和正确实现
如果一个算法只对小的输入运行,运行时间增长率比运行时间前面的常数因子显得不重要,可选常数因子小,而增长率大的算法 3、非递归算法的数学分析
决定用哪个(哪些)参数作为输入规模的度量 找出算法的基本操作
检查基本操作的执行次数是否只依赖输入规模,如果还依赖其他特性则应区分最差、平均及最优效率
建立算法基本操作执行次数的求和公式 对求和公式求解,至少应确定其增长次数
4、递归算法的数学分析 (归并排序、汉诺塔递归解法的时间复杂度) 一个过程在运行时直接或间接地调用自己,则该过程称为递归程序。 决定用哪个(哪些)参数作为输入规模的度量 找出算法的基本操作
检查基本操作的执行次数是否只依赖输入规模,如果还依赖其他特性则应区分最差、平均及最优效率
对算法基本操作的执行次数建立一个递推关系式以及相应的初始条件 求解递归关系式,至少确定其增长次数
二、 递归与分治算法 1、归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 2、快速排序
快速排序(Quicksort)是对冒泡排序的一种改进。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 3、二分查找
二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。 4、棋盘覆盖问题
在一个2^k×2^k (k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格。显然,特殊方格在棋盘中可能出现的位置有4^k种,因而有4^k种不同的棋盘,图4.10(a)所示是k=2时16种棋盘中的一个。棋盘覆盖问题(chess cover problem)要求用图4.10(b)所示的4种不同形状的L型骨牌覆盖给定棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
当 k>0 时,将2k×2k棋盘分割为4个2k-1×2k-1 子棋盘。
特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。
为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,从而将原问题转化为4个较小规模的棋盘覆盖问题。递归地使用这种分割,直至棋盘简化为棋盘1×1。
5、放苹果 http://poj.org/problem?id=1664 Description
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。 Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。 Output
对输入的每组数据M和N,用一行输出相应的K。 Sample Input 1 7 3
Sample Output 8
Source
三、 贪心算法 1、活动安排问题
活动安排问题是可以使用贪心算法有效求解的很好的例子。
设有n个活动的集合E={1,2,??,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si
2、背包问题
背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。相似问题经常出现在商业、组合数学,计算复杂性理论、密码学和应用数学等领域中。也可以将背包问题描述为决定性问题,即在总重量不超过W的前提下,总价值是否能达到V?它是在1978年由Merkel和Hellman提出的。
3、多机调度问题 1、问题描述
设有n个独立的作业{1, 2, ?, n}, 由m台相同的机器进行加工处理. 作业i所需时间为t i. 约定:任何作业可以在任何一台机器上加工处理, 但未完工前不允许中断处理,任何作业不能拆分成更小的子作业。要求给出一种作业调度方案,使所给的n 个作业在尽可能短的时间内由m台机器加工处理完成。
多机调度问题是一个NP完全问题,到目前为止还没有完全有效的解法。对于这类问题,用贪心选择策略有时可以设计出一个比较好的近似算法。
4、Gone Fishing http://poj.org/problem?id=1042
Description
John is going on a fishing trip. He has h hours available (1 <= h <= 16), and there are n lakes in the area (2 <= n <= 25) all reachable along a single, one-way road. John starts at lake 1, but he can finish at any lake he wants. He can only travel from one lake to the next one, but he does not have to stop at any lake unless he wishes to. For each i = 1,...,n - 1, the number of 5-minute intervals it takes to travel from lake i to lake i + 1 is denoted ti (0 < ti <=192). For example, t3 = 4 means that it takes 20 minutes to travel from lake 3 to lake 4. To help plan his fishing trip, John has gathered some information about the lakes. For each lake i, the number of fish expected to be caught in the initial 5 minutes, denoted fi( fi >= 0 ), is known. Each 5 minutes of fishing decreases the number of fish expected to be caught in the next 5-minute interval by a constant rate of di (di >= 0). If the number of fish expected to be caught in an interval is less than or equal to di , there will be no more fish left in the lake in the next interval. To simplify the planning, John assumes that no one else will be fishing at the lakes to affect the number of fish he expects to catch.
Write a program to help John plan his fishing trip to maximize the number of fish expected to be caught. The number of minutes spent at each lake must be a multiple of 5. Input
You will be given a number of cases in the input. Each case starts with a line containing n. This is followed by a line containing h. Next, there is a line of n integers specifying fi (1 <= i <=n), then a line of n integers di (1 <=i <=n), and finally, a line of n - 1 integers ti (1 <=i <=n - 1). Input is terminated by a case in which n = 0.
Output
For each test case, print the number of minutes spent at each lake, separated by commas, for the plan achieving the maximum number of fish expected to be caught (you should print the entire plan on one line even if it exceeds 80 characters). This is followed by a line containing the number of fish expected.
If multiple plans exist, choose the one that spends as long as possible at lake 1, even if no fish are expected to be caught in some intervals. If there is still a tie, choose the one that spends as long as possible at lake 2, and so on. Insert a blank line between cases. Sample Input 2 1 10 1 2 5 2 4 4
10 15 20 17 0 3 4 3 1 2 3 4 4
10 15 50 30
0 3 4 3 1 2 3 0
Sample Output 45, 5
Number of fish expected: 31 240, 0, 0, 0
Number of fish expected: 480 115, 10, 50, 35
Number of fish expected: 724 Source
四、 动态规划算法
1、数字三角最大路径问题
多边形的三角剖分是将多边形分割成互不相交的三角形的弦的集合T。
给定凸多边形P,以及定义在由多边形的边和弦组成的三角形上的权函数w。要求确定该凸多边形的三角剖分,使得该三角剖分中诸三角形上权之和为最小。
2、矩阵连乘问题
给定n个矩阵,要求计算这n个矩阵的连乘积
矩阵乘法满足结合律,计算矩阵的连乘积可以有许多不同的计算次序 用加括号的方式确定计算次序
若一个矩阵连乘积的计算次序完全确定,则称该连乘积是完全加括号的 void matrixMultiply(int ** a, int ** b, int ** c, int ra, int ca, int rb, int cb) {
if( ca != rb) error(“矩阵不可乘”); for(int i = 0; i < ra; i ++) for(int j = 0; j < cb; j ++){ int sum = a[i][0] * b[0][j]; for(int k = 1; k < ca; k++) sum += a[i][k] * b[k][j]; c[i][j] = sum; } }
3、0-1背包问题
给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 0-1背包问题是一个特殊的整数规划问题。
五、 回溯法 1、装载问题
有一批集装箱要装上一艘载重量为c的轮船。其中集装箱i的重量为Wi。最优装载问题要求