我是靠谱客的博主 刻苦灰狼,最近开发中收集的这篇文章主要介绍算法设计与分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.一辆汽车加满油后可行驶n公里。指出应在哪些加油站停靠加油,使沿途加油次数最少。阅读程序1,回答问题。

代码的输入和输出分别是什么?

数据输入:

n:表示汽车加满油后可行驶nkm

k:旅途中有k个加油站

k+1个整数:表示第k个加油站与第k-1个加油站之间的距离。第0个加油站表示出发地,汽车已加满油。第k+1个加油站表示目的地。

数据输出:最少加油次数和具体在哪几个加油站加油。 

(2)代码选用的数据结构是什么?

数组 

(3)代码选用的算法设计策略是?

如果要使用贪心算法解决问题,那么需要检查每一小段路程是否超过汽车满油量时的最大支撑路程。如果有超过的,那么汽车不可能走完这段路。否则,找到汽车满油量时的最大支撑路程范围内的最后一个加油站,加油后继续用此方法前进

2.阅读算法1,回答问题。

middle=(low+high)/2;  //计算middle值(查找范围的中间值)

                 //x大于s[middle],则在后半部分查找    return BinarySearch(s,x,middle+1,high);

}

(1)算法1的功能是什么?(3分)

 二分搜索

请你设计至少4组输入,验证算法1的正确性。(4分)

[1,2,3],[1,3,3],[1,3,3],[1,333],[123321]

请改用自然语言描述算法1。(3分)

折半查找,每次减少一半范围,log2时间即可找到

3.阅读算法2,回答问题。

算法2:kn(int w[],int v[],int n,int C)//参数分别为物品重量、物品价值、物品数量、容量

   算法2设计策略是什么?(1分)

贪心策略:选择单位重量价值最大的物品

请根据算法2,写出递归关系式。

if(j>=w[i-1])

       dp[i][j]=max(dp[i+1][j],dp[i+1][j-w[i-1]])+v[i-1];

else dp[i][j]= dp[i+1][j];

4.阿里巴巴走进了装满宝藏的藏宝洞。请问阿里巴巴最多可以拿走多少价值的金币?

(1)请给出存储已知数据的数据结构数组

请给出你选择的算法策略

先将每堆金币按金币的价值重量比进行排序,越高的排在越前面,然后从前往后一堆一堆的放入背包,当背包装不下某一堆金币时,则取这堆金币的部分装入,使得装入的金币总重量等于背包的承重量即可。

5.游艇俱乐部在长江上设置了n个游艇出租站。求解从游艇出租站1到游艇出租站n所需的最少的租金。

(1)写出选用的算法策略(2分)。

动态规划算法

(2)写出该算法策略的思想(4分)。

【令dp[i]表示从站点1到站点i所需的最少租金

dp[1]=r[1][1]=0,dp[2]=r[1][2],

递推关系:dp[i]=min(dp[i],dp[j]+r[j]),1】

dp[i][j]表示第i个站点到第j个站点的最少租金。枚举2个站点的最少租金,3个站点的最少租金,…,n个站点的最少租金。状态转移方程:

写出求解问题所用的数据结构

数据结构:两个二维数组r[][]和dp[][]。

写出求解问题的算法步骤

void rent(){

        for(int d=3;d<=n;d++){//区间长度d

          for(int i=1;i<=n-d+1;i++){//状态起点i,终点j

            int j=i+d-1;

            for(int k=i+1;k<j;k++){//枚举决策点k 

                if(dp[i][j]>dp[i][k]+dp[k][j])

                    dp[i][j]=dp[i][k]+dp[k][j];

            }

          }

   }

}

(5)分析算法的时间复杂度和空间复杂度。时间复杂度:O(n3),空间复杂度:O(n2)。

6.分析算法3的时间复杂度和空间复杂度。

        while(i<j && r[j]>pivot)  j--; //从右向左扫描

        if(i<j)

            swap(r[i++], r[j]);

        while(i<j && r[i]<=pivot)  i++; //从左向右扫描

时间复杂度O(n)和空间复杂度O(n)

7.请分析算法4的时间复杂度和空间复杂度,并给出一个更好的求解方法及求解步骤。

算法4: nQueens (int t)

                  nQueens(t+1);

           }

}

时间复杂度 O(n*2^n) 空间复杂度 O(n*n)

8.请分析算法5的时间复杂度和空间复杂度,并给出算法5的非递归算法。

算法5:

Def  backtrack( t){//地图着色问题

Global colors,x,sum1,n,m,a

if(t>n){ //到达叶子,找到一个着色方案

本算法运算时需要对每个点的每个邻接进行判断,为(2×e)次判断操作,及给没上色的点上色,有v次操作,一共(2×e)+v次操作,由于在着色问题当中,边数(所有邻接省份数)比点数(省份数)多,所以时间复杂度可认为是θ(v)。

运算时创建了一个额外的队列来记录待遍历的点,所以空间复杂度为(e)。

9.三个矩阵大小分别为3*4、4*5、5*6,求其相乘的最优结合次序。

(1)写出所用的求解方法(4分)

动态规划方法

描述该方法求解的步骤(4分)

定义一个二维数组m存储最少乘法次数,二维数组s存储最优决策并分别初始化为0;(1分)

按照区间长度(即j-i)升序的原则,依次采用下式计算所有的m[i][j]和s[i][j]:

m[i][j]=min{m[i][k]+m[k+1][j]+P[i-1]P[k]P[j]},i<=k<j (1分)

而s[i][j]设置为达到最小值的k值;(1分)

根据从s[1][n]开始,从s的值依次构造最优解(1分)

给出求解过程(4分)

区间长度为1: (2分)

m[1][2]=P[0]P[1]P[2]=3*4*5=60,s[1][2]=1;

m[2][3]=P[1]P[2]P[3]=4*5*6=120,s[1][2]=2;

区间长度为2:(2分)

m[1][3]=min(m[1][2]+P[0]P[2]P[3],m[2][3]+P[0]P[1]P[3])=min(150,192)=150,s[1][3]=2

(4)给出求解结果(2分)。 

构造解:根据s的值可知最优相乘次序为 (A1*A2)*A3(2分)。

 

 

 

1.阅读“算法1”,分析算法1的功能、时间复杂度。

功能:求解汉诺塔问题,将n个盘子从A塔,借助B塔,移动到C塔上。

时间复杂度:

T(n)=2T(n-1)+O(1)=4T(n-2)+2O(1)+O(1)=....=(2^n-1+2^n-2+...+1)O(1)=O(2^n)

2.阅读“算法2”,分析算法2的功能,设计算法的一个输入,并给出对应的算法输出结果。

功能:将arr中的整数按照由小到大的顺序排序,选择排序法

输入:arr=[6,24,3,21,25,4]

输出:3,4,6,21,24,25

3.“算法3”为回溯法求无向不带权图G的最大团问题的递归函数backtrack(),请您依据递归函数,写出该问题解的形式、解空间的组织结构和搜索条件。假设用邻接矩阵g[][]存储无向不带权图G。

解的形式:(x1,x2,...,xn),其中xi表示第i个顶点是否在最大团中,xi=0:表示不在最大团中,xi=1:表示在最大团中.

解空间组织结构:满二叉树,深度为n或n+1

搜索条件:约束条件:任何两个顶点之间都有边相连

限界条件:预估的当前节点的最大团的顶点个数上界cn+rn大于当前找到的最大团中的顶点个数bestn

约束函数:

def place(t):

    OK=True

    for j in range(t):

        if x[j] and a[t][j]==0:

            OK=False

            break

    return OK

4.阅读“算法4”,算法4中的time为结构体数据类型,定义了开始时间start_time和结束时间end_time两个数据项,请您设计一个n=6的实例,并给出算法4得到的x的值。

输入:(2,3),(1,2),(3,8),(1,6),(7,9),(5,7)

按照结束时间由小到大排序结果为:(1,2),(2,3),(1,6),(5,7),(3,8),(7,9)

输出x的值为(1,1,0,1,0,1)

5.阅读“算法5”,分析算法的功能,并给出一个例子,展示算法的运行过程。

算法5: MergeSort (int A[],int low,int high)

              Merge(A,low,middle,high); //将两个有序子序列A[low:middle]、

A[middle+1:high]合并为一个有序序列

算法功能:合并排序,将一个无序序列按照由小到大的顺序排列

例子:3,8,2,10,8,90

过程:

分:【3,8,2】,【10,8,90】

分:【3,8】【2】

分【3】【8】

治:【3,8】

治【2,3,8】

分:【10,8】【9】

分:【10】【8】

治【8,10】

治【8,9,10】

治【2,3,8,8,9,10】

6.给定5种字符a,b,c,d,e及它们出现的频率0.45,0.25,0.15,0.10,0.05,选择一种编码方法,求这5个字符的编码方案。

(1)哈夫曼编码,把字符看作孤立的根节点组树的集合,依次从集合中选择两个频率最小的字符,组成左右子树构造一个新树,新树的频率是左右子树频率之和,然后把新树插入到树的集合中,一次重复,直到树集合只剩下一课树为止。把左子树赋值为1,右子树赋值为0,从根到叶子的路径就是对应叶子字符的编码。

(2)a:0,b:10,c:110;d:1111,e:1110

(3)平均码长为:1*0.45+2*0.25+3*0.15+4*0.10+4*0.05=2

7.定序列X={E,F,G,A, B,E}和Y={E,B, D, F,A, G},求它们的最长公共子序列。

(1)动态规划法

(2)最优子结构性质分析,建立最优值的递归关系式,自底向上求最优值,构造最优解

(3) 0 0 0 0 0 0 0

         0 1 1 1 1 1 1

         0 1 1 1 2 2 2

         0 1 1 1 2 2 3

         0 1 1 1 2 3 3

         0 1 1 1 2 3 3

         0 1 1 1 2 3 3

(4)最长公共子序列为E,F,G

8.0-1背包问题:给定n个物品,1个背包,背包容量为W,n个物品的重量和价值分别为:(wi,vi)i=1,2,3,...,n。物品不能分割,请设计一算法,求解在不超过背包容量的前提下,怎么装能够使得装入的物品总价值最大。

(1)回溯法

(2)搜索思想:

从根开始,以深度优先搜索的方式进行搜索。

根结点是活结点并且是当前的扩展结点。在搜索的过程中,当前的扩展结点向纵深方向移向一个新结点,判断该新结点是否满足隐约束。

如果满足,则新结点成为活结点,并且成为当前的扩展结点,继续深一层的搜索;

如果不满足,则换该新结点的兄弟结点(扩展结点的其它分支)继续搜索;

如果新结点没有兄弟结点,或其兄弟结点已全部搜索完毕,则扩展结点成为死结点,搜索回溯到其父结点处继续进行。

搜索过程直到找到问题的解或根结点变成死结点为止。 

(3)将物品数据用三元组(编号,重量,价值),然后用顺序表存储物品,用顺序表存储n维0-1向量。

(4)

def bound(i):

    global c,curW,goods,curV,n#goods物品物品集合:物品编号、物品重量、物品价值

    cleft = c - curW

    b=curV;

    while(i<=n and goods[i][1]<=cleft):

        cleft -= goods[i][1]

        b +=goods[i][2]

        i +=1

    if(i<=n):

        b += goods[i][2]/goods[i][1]*cleft;

    return b

def backtrack(t):

    global bestV,curW,curV,x,bestx,n,goods#物品集:物品编号、物品重量、物品价值

    if t>=n:

        if bestV < curV:

            bestV = curV

            bestx = x[:]

    else:

        if curW + goods[t][1] <= c:

            x[goods[t][0]] = 1

            curW += goods[t][1]

            curV += goods[t][2]

            backtrack(t+1)

            curW -= goods[t][1]

            curV -= goods[t][2]

        if bound(t) > bestV:

            x[goods[t][0]]=0

            backtrack(t+1)

9.最优装载问题:给定n个箱子,其重量为wi(i=1,2,3,...,n)),某艘船的载重量为C,船的体积不受限制,在不超过船的载重量的前提下,设计一算法,将尽量多的箱子装到船上。

(1)回溯法

(2)搜索思想:

从根开始,以深度优先搜索的方式进行搜索。

根结点是活结点并且是当前的扩展结点。在搜索的过程中,当前的扩展结点向纵深方向移向一个新结点,判断该新结点是否满足隐约束。

如果满足,则新结点成为活结点,并且成为当前的扩展结点,继续深一层的搜索;

如果不满足,则换该新结点的兄弟结点(扩展结点的其它分支)继续搜索;

如果新结点没有兄弟结点,或其兄弟结点已全部搜索完毕,则扩展结点成为死结点,搜索回溯到其父结点处继续进行。

搜索过程直到找到问题的解或根结点变成死结点为止。 

(3)用顺序表w存储箱子重量,用顺序表x存储n维0-1向量。

(4)

def backtrack(t):

    if t>n:

        if bestn< curn:

            bestn = curn

            bestx = x[:]

    else:

        if curW + w[t] <= C:

            x[t] = 1

            backtrack(t+1)

        if curn+rn > bestn:

            x[t]=0

            backtrack(t+1)

最后

以上就是刻苦灰狼为你收集整理的算法设计与分析的全部内容,希望文章能够帮你解决算法设计与分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部