一:算法时间复杂性
1.写出下列非递归程序的时间复杂性
(1)
for(i=2;i<=n;++i)
for(j=2;j<=i-1;++j)
{ ++x;
a[i,j]=x;
}
上述程序的时间复杂性为:O(n^2)
(2)
int i,j x=0;
for (i=1;i<n;++i)
{
for (j=i+1;j<=n;++j)
{++x}
}
上述程序的时间复杂性为: O(n^2)
(3)
int i=1;
while(i<=n)
i=i*2;
上述程序的时间复杂性为: O(logn)
- 写出下列递归程序的时间复杂性
int f(int n)
{
if (n==1)
{return 1;}
else
{
return f(n-1)+f(n-2);
}
}
上述递归程序的时间复杂性为:O(2^n)
求解过程:
以f(6)为例:斐波那契数列到第六个数停止
为了计算简便,把第5层fib(1)和fib(2)放在第4层最右边,不影响时间复杂度的计算
可知F(6)有4层,即推得F(n)有n-2层
亦得第n层节点个数:2^n 个
所以,前n层节点个数:1+2+4+……+2^n = (2 ^ n) – 1
二叉树的高度是 n - 2,也就是递归过程函数调用的次数,所以时间复杂度为 O(2^n)。
二:贪心算法设计题
写出求解最大团问题的贪心算法的步骤。
最大团问题简介:一个无向图 G=(V,E),V 是点集,E 是边集。取 V 的一个子集 U,若对于 U 中任意两个点 u 和 v,有边 (u,v)∈E,那么称 U 是 G 的一个完全子图。 U 是一个团当且仅当 U 不被包含在一个更大的完全子图中。G的最大团指的是定点数最多的一个团。
解: 1.随机从点集V中选择一个点v1,v1自身构成一个完全子图U,标记为flag。
2.遍历v1的相邻边,枚举与其相连接的点(不在U中),若无邻接点,重复步骤1,否则执行步骤3。
3.选择第一个与v1相连的点v2,判断其与完全子图U中任意点是否均相连,若均相连,则将v2加入U中,否则继续遍历枚举其他点直至遍历结束,执行步骤4.
4.从U中选择一个未标记为flag的点u作为遍历中心,重复步骤2,待U中所有点均标记为flag时结束,此时的U是G的最大团。
三:回溯算法设计题
- 写出求解0-1背包问题的回溯算法的步骤
0-1背包问题简介::给定n 种物品和一背包。物品 i 的重量为 wi,其价值为 pi,背包的容量为 c。问应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?
解:
使用子集树表示0-1背包问题的解空间。
计算右子树中解的上界的时将剩余物品依其单位重量价值排序,然后依次装入物品,直至装不下时,再装入物品的一部分而装满背包。由此得到的价值是右子树中解的上界。
而进入左子树时不需要计算上界,因为其上界与其父节点上界相同。
以下是动态规划转移方程和计算步骤
dp[n][wi]=max(dp[n-1][w(i-1)-wi]+pi,dp[n-1][wi])
1.计算每种物品单位重量的价值si=pi/wi=[6,5,4,3]
2.依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。
3.若将这种物品全部装入背包后,背包内的物品总重量未超过c,则选择单位重量价值次高的物品并尽可能多地装入背包。
4.依此策略一直地进行下去,直到背包装满为止
2.画出求解下面0-1背包问题的二叉树
n = 4,(wi) = (30, 40, 30, 10),(pi) = (180, 200, 120, 30),c = 95。
其中n为物品个数,wi为物品的重量,pi为物品的价值,c为背包总重量限制。
解: