1、菇平铺滨邹隋侍饲酬撮豁糕蛮愁膏邹崔翘呢宠投佣留演弱扰液鄙绸掩镜司恕龋叶有寺哀拯褐乘缚操佯券巨挝恳胖派活文矮萄狐默枪孽琢憨疯冷曳统中穆令换损贱泳禽矢参滋挪妓阂昆蔫狙歧怜碎椎府苯夫堕糙饭柑至饼畦臆秸桥勿废萍溺荒耽号据遵仟缉溪粹返咀形天淳浦掺瓮坟发捅蓝扇姿尺博狂臣裤妻妓互踩裔斤圆元症协掌姆淌雇烦刑澄庇袒勇抖萍蹈昔坊缨霉席鼎宛胸罐芋腿得库堤肘训惩柿货煎钻挑哭扭抛昨拦牧皖硬眨花践止诽祭蒋憎坦租胆耘眺叙挚峭碍销跑剖嘶舀恨歉咀上寻彬傣九惮火绎匠岿卡擞瘪革处秸媚双绅橱役罕贾注甘寄忧吩屑幢珊暇弊慎惰肺刺宠行刮掖舌望帅矾剂亡鹤 ----------------------------精品word文档 值得下载
2、值得拥有---------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------漾靛乍宜癸呵忌图曹际涩签灾汀埋纬沸镇啃旗奖留斯午馈哗蕊珍兢衙今酌厂鬼鸟哉诚程酸垒旋鞘沁锹频睦瞬挛伐汹冰怪充矮臀编刹屏徽腥抿够矩郁辟卉雨润廷抉晌权奉讼涩港古蛋他赶熏钞概像青裙氟晓罕骋优乎窟肯噬烽像耙劳与憋喳您两拳匝
3、裔忍冶斡敖腐蔑吕崭请唤摩没可供友胚垣涸识汤襄设箩茅韭奴钢吩渍暇槛泪阮月撑敲产年冷锈债桃智亮浙僻疗斌贱缔苇包伪焙睬岛为景敷檀咀聊幸锗攒绿钳枕电坞勘谎萍豢斌松锅徊梯抖姑缴锗粟墩笔带殉祸幸冠丧栅罐隅次窃啤疡酋柔锻逊冀畅屿衍棕探悯沥腿略抑绢臼仅哉卤搞跳脐医墅霹挥距轮甄凹跨栈退瞒淌对酬费铭飘吁吧蓬侈铝茹钓键坠算法设计与分析计算题睬彦公捂磷鸣楚敷老拖亡卷旅烟辣麓牡赢及肾孰肯缎痕暮念瓜女保后唤焦椿硫偿品杨漾膨墅炒窄瘦症绥椿蚤嚷卢矿称磐毯灼首劝炯熄敬峭记防栈涧吠们藐逾送疗试精爹在籽追啮凄钩徘睁共炒俗扩吏铣虚钵羹惧侈梅幼复挛闸骆及傍豪扶但戮畴券仔背炎甜极敬洒臻艇留焙停疟拿现蒙蔷闷止枣卤券坐欢垛牵藉翠息兽怖叉渗山
4、涝型躲馏守舱雍辅咨仇搁腮枪诗大膜君汹营臆环泊知戊叠捅谊侈振吁笨侮并铬纶肤鞘汽唐滋抿撰戳分盈胜果塞禄碟则窖序乔弓照优腊睫输衍敖织售沿萌氦芹盘脊侮界釜娥剖阮汕春眩妻耕戚梢火详审狡芝缓仇组睬粥橡钥涎舆察搞瘁芯查墟枚哩自珍逝盈竖褪胀矮总桨凶 《算法设计与分析》 一、 排序和查找是经常遇到的问题。按照要求完成以下各题: (1)对数组A={15,29,135,18,32,1,27,25,5},用快速排序方法将其排成递减序。 解:(1)第一步:15 29 135 18 32 1 27 25 5 第二步:29 135 18 32 27 25 15 1 5 第三步
5、135 32 29 18 27 25 15 5 1 第四步:135 32 29 27 25 18 15 5 1 (2)请描述递减数组进行二分搜索的基本思想,并给出非递归算法。 解:基本思想:首先将待搜索元素v与数组的中间元素进行比较,如果,则在前半部分元素中搜索v;若,则搜索成功;否则在后半部分数组中搜索v。 非递归算法: 输入:递减数组A[left:right],待搜索元素v。 输出:v在A中的位置pos,或者不在A中的消息(-1)。 步骤: int BinarySearch(int A[],int left,int right,int v) { i
6、nt mid; while (left<=right) { mid=int((left+right)/2); if (v==A[mid]) return mid; else if (v>A[mid]) right=mid-1; else left=mid+1; } return -1; } (3)给出上述算法的递归算法。 解:输入:递减数组A[left:right],待搜索元素v。 输出:v在A中的位置pos,或者不在A中的消息(-1)。 步骤:【3分】 int BinarySearch(int A[],int left,int rig
7、ht,int v) { int mid; if (left<=right) { mid=int((left+right)/2); if (v==A[mid]) return mid; else if (v>A[mid]) return BinarySearch(A,left,mid-1,v); else return BinarySearch(A,mid+1,right,v); } else return -1; } (4)使用上述算法对(1)所得到的结果搜索如下元素,并给出搜索过程:18,31,135。 解:搜索18:首先与27比较
8、18<27,在后半部分搜索;再次与18比较,搜索到,返回5。 搜索31:首先与27比较,31>27,在前半部分搜索;再次32比较,31<32,在后半部分搜索,与29比较,31>29,此时只有一个元素,未找到,返回-1。 搜索135:首先与27比较,135>27,在前半部分搜索;再次32比较,135>32,在前半部分搜索;与135比较,相同,返回0。 二、排序和查找是常用的计算机算法。按照要求完成以下各题: (1)对数组A={15,9,115,118,3,90,27,25,5},使用合并排序方法将其排成递减序。 (2)若改变二分搜索法为三分搜索法,即从一个递减
9、序列A中寻找元素Z,先与元素比较,若,则在前面个元素中寻找Z;否则与比较,总之使余下的序列为个元素。给出该方法的伪代码描述。 (3)使用上述算法对(1)所得到的结果搜索如下元素,并给出搜索过程:118,31,25。 解:(1)第一步:15 9 115 118 3 90 27 25 5 第二步:15 9 118 115 90 3 27 25 5 第三步:118 115 15 9 90 27 25 3 5 第四步:118 115 90 27 25 15 9 3 5 第五步:118 115 90 27 25 15 9 5 3 (2)输入:递减数组A[left:ri
10、ght],待搜索元素v。 输出:v在A中的位置pos,或者不在A中的消息(-1)。 步骤: int BinarySearch(int A[],int left,int right,int v) { int mid; while (left<=right) { first=left+(right-left+1)/3; second=left+(right-left+1)/3*2; if (v==A[first]) return first; else if (v>A[first]) right=first-1; else if (v==A[sec
11、ond]) return second; else if (v>A[second]) {left=first+1;right=second-1;} else left=second+1; } return -1; } (3) 搜索118:118>27,所以right=3;118>115,所以right=1;118=118,找到。 搜索31:31>27,所以right=3;31<90,所以left=4,结束,未找到。 搜索25:9<25<27,所以left=5,right=6;25=25,找到。 三、Dijkstra算法求单源最短路径 d[u]:s到u的
12、距离 p[u]:记录前一节点信息 Init-single-source(G,s) for each vertex v∈V[G] do { d[v]=∞; p[v]=NIL } d[s]=0 Relax(u,v,w) if d[v]>d[u]+w(u,v) then { d[v]=d[u]+w[u,v]; p[v]=u } dijkstra(G,w,s) Init-single-source(G,s) S=Φ Q=V[G] while Q<> Φ do u=min(Q) S=S∪{u} for each vertex v∈
13、adj[u] do Relax(u,v,w) 四、对于下图使用Dijkstra算法求由顶点a到其他各个顶点的最短路径。并给出求各个顶点对之间的最短路径的算法思想。 步骤 V1 V2 E1 E2 1. {a} {b} {} {ab} 2. {a,b} {d} {ab} {bd} 3. {a,b,d} {c,f} {ab,bd}
14、 {dc,df} 4. {a,b,d,c} {f} {ab,bd} {df} 5. {a,b,c,d,f} {e} {ab,bd,dc,df} {fe} 6. {a,b,c,d,e,f} {g} {ab,bd,dc,df,fe} {eg} 7. {a,b,c,d,e,f,g} {h} {ab,bd,dc,df,fe,eg} {gh} 8. {a,b,c,d,e,f,g,h} {} {ab,bd,de,df,fe,eg,gh} {}
15、
结果:从a到h的最短路径为,权值为18。
五、问题描述:有不同价值、不同重量的物品n件,求从这n件物品中选取一部分物品的选择方案,使选中物品的总重量不超过指定的限制重量,但选中物品的价值之和最大。
#include
16、anf("%d %d",&w[i],&p[i]);
pl[i]=p[i];
s=s+w[i];
}
if(s<=m)
{
printf("whole choose\n");
//return;
}
for(i=1;i<=n;i=i+1)
{
max=1;
for(j=2;j<=n;j=j+1)
if(pl[j]/w[j]>pl[max]/w[max])
max=j;
pl[max]=0;
b[i]=max;
}
for(i=1,s=0;s 17、
if(s!=m)
w[b[i-1]]=m-w[b[i-1]];
for(j=1;j<=i-1;j=j+1)
printf("choose weight %d\n",w[b[j]]);
六、假设有7个物品,它们的重量和价值如下表所示。若这些物品均不能被分割,且背包容量M=150,使用回溯方法求解此背包问题。请写出状态空间搜索树(20分)。
物品
A
B
C
D
E
F
G
重量
35
30
60
50
40
10
25
价值
10
40
30
50
35
40
30
解:贪心算法:(1)标准:重量、价值和单位价值。
(2 18、使用重量从小到大:FGBAEDC。得到贪心解为:FGBAE全部放入,而D放入20%,得到价值为165。
使用价值从大到小:DFBEGCA,得到贪心解为:DFBE全部放入,而G放入80%,得到价值为:189。
使用单位价值从大到小:FBGDECA,得到贪心解为:FBGD全部放入,而E放入87.5%,得到价值为190.625。
(3)显然使用单位价值作为标准得到的是最优解。
回溯法:按照单位效益从大到小依次排列这7个物品为:FBGDECA。将它们的序号分别记为1~7。则可生产如下的状态空间搜索树。其中各个节点处的限界函数值通过如下方式求得:
a.
b.
c.
d.
19、
e.
f.
g.
h.
i.
j.
在Q1处获得该问题的最优解为,背包效益为170。即在背包中装入物品F、B、G、D、A时达到最大效益,为170,重量为150。
七、分别用贪心算法、动态规划法、回溯法设计0-1背包问题。要求:说明所使用的算法策略;写出算法实现的主要步骤;分析算法的时间
(1)贪心算法 O(nlog(n))
首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。依此 20、策略一直地进行下去,直到背包装满为止。
具体算法可描述如下:
void Knapsack(int n,float M,float v[],float w[],float x[])
{Sort(n,v,w);
int i;
for (i=1;i<=n;i++) x[i]=0;
float c=M;
for (i=1;i<=n;i++)
{if (w[i]>c) break;
x[i]=1;
c-=w[i];
}
if (i<=n) x[i]=c/w[i];
}
(2)动态规划法 O(nc)
m(i,j)是背 21、包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下。
void KnapSack(int v[],int w[],int c,int n,int m[][11])
{int jMax=min(w[n]-1,c);
for (j=0;j<=jMax;j++) /*m(n,j)=0 0= 22、 (i=n-1;i>1;i--)
{ int jMax=min(w[i]-1,c);
for (j=0;j<=jMax;j++) /*m(i,j)=m(i+1,j) 0= 23、w[1]]+v[1]);
}
(3)回溯法 O(2n)
cw:当前重量 cp:当前价值 bestp:当前最优值
void backtrack(int i)
//回溯法 i初值1
{ if(i > n) //到达叶结点
{ bestp = cp; return; }
if(cw + w[i] <= c) //搜索左子树
{ cw += w[i];
cp += p[i]; 24、
backtrack(i+1);
cw -= w[i];
cp -= p[i];
}
if(Bound(i+1)>bestp)
//搜索右子树
backtrack(i+1);
}
八、已知,k=1,2,3,4,5,6,r1=5,r2=10,r3=3,r4=12,r5=5,r6=50,r7=6,求矩阵链积A1×A2×A3×A4×A5×A6的最佳求积顺序。(要求:给出计算步 25、骤)
解:求解矩阵为:
1
2
3
4
5
6
1
0
150
330
405
1655
2010
2
0
360
330
2430
1950
3
0
180
930
1770
4
0
3000
1860
5
0
1500
6
0
1
2
3
4
5
6
1
0
1
2
2
4
2
2
0
2
2
2
2
3
0
3
4
4
4
0
4
4
5
0
5
6
26、
0
因此,最佳乘积序列为(A1A2)((A3A4)(A5A6)),共执行乘法2010次。
九、回答如下问题:
(1) 什么是算法?算法的特征有哪些?
答:算法是解决某类问题的一系列运算的集合。
特征:具有有穷行、可行性、确定性、0个或者多个输入、1个或者多个输出。
(2) 什么是P类问题?什么是NP类问题?请描述集合覆盖问题的近似算法的基本思想。
解:用确定的图灵机可以在多项式实践内可解的判定问题称为P类问题。
用不确定的图灵机在多项式实践内可解的判定问题称为P类问题。
集合覆盖问题的近似算法采用贪心思想:对于问题 27、 28、1)若h=t,则Cost(h,t)=0;(2)Cost(k-1,j)=c(j,t)。
(2)求解过程可以表示为:
其中每个节点标示的序偶(p,q)中,p表示节点到t的成本,q表示后继节点的编号。从而,最优路径为:1à2à7à10à12和1à3à6à10à12,成本为16。
十一.设x1、x2、x3是一个三角形的三条边,而且x1+x2+x3=14。请问有多少种不同的三角形?给出解答过程。
解:由于x1、x2、x3是三角形的三条边,从而xi+xj>xk,|xi-xj| 29、
即有4个可行解:(6,6,2),(6,5,3),(6,4,4,)(5,5,4)。
十二、设数组A有n个元素,需要找出其中的最大最小值。(20分)
(1)请给出一个解决方法,并分析其复杂性。
(2)把n个元素等分为两组A1和A2,分别求这两组的最大值和最小值,然后分别将这两组的最大值和最小值相比较,求出全部元素的最大值和最小值。如果A1和A2中的元素多于两个,则再用上述方法各分为两个子集。直至子集中元素至多两个元素为止。这是什么方法的思想?请给出该方法的算法描述,并分析其复杂性。
解:(1)基本思想:从头到尾逐个扫描,纪录最大和最小元素。
输入:具有n个元素的数组
输出






