算法分析与设计(李清勇)课后习题答案.docx
《算法分析与设计(李清勇)课后习题答案.docx》由会员分享,可在线阅读,更多相关《算法分析与设计(李清勇)课后习题答案.docx(16页珍藏版)》请在冰豆网上搜索。
5-1凸多边形最优三角剖分问题
//3d5凸多边形最优三角剖分
#include"stdafx.h"#includeusingnamespacestd;
constintN=7;//凸多边形边数+1
intweight[][N]={{0,2,2,3,1,4},{2,0,1,5,2,3},{2,1,0,2,1,4},{3,5,2,0,6,2},{1,2,1,6,0,1},{4,3,4,2,1,0}};//凸多边形的权
intMinWeightTriangulation(intn,int**t,int**s);
voidTraceback(inti,intj,int**s);//构造最优解
intWeight(inta,intb,intc);//权函数
intmain(){
int**s=newint*[N];
int**t=newint*[N];
for(inti=0;is[i]=newint[N];
t[i]=newint[N];
}
cout<<"此多边形的最优三角剖分值为:
"<cout<<"最优三角剖分结构为:
"<Traceback(1,5,s);//s[i][j]记录了Vi-1和Vj构成三角形的第3个顶点的位置
return0;
}
intMinWeightTriangulation(intn,int**t,int**s)
{
for(inti=1;i<=n;i++)
{
t[i][i]=0;
}
for(intr=2;r<=n;r++)//r为当前计算的链长(子问题规模)
{
for(inti=1;i<=n-r+1;i++)//n-r+1为最后一个r链的前边界
{
intj=i+r-1;//计算前边界为r,链长为r的链的后边界
t[i][j]=t[i+1][j]+Weight(i-1,i,j);//将链ij划分为A(i)*(A[i+1:
j])这里实际上就是k=i
s[i][j]=i;
for(intk=i+1;k //将链ij划分为(A[i:
k])*(A[k+1:
j])
intu=t[i][k]+t[k+1][j]+Weight(i-1,k,j);
if(u t[i][j]=u;
s[i][j]=k;
}
}
}
}
returnt[1][N-2];
}
voidTraceback(inti,intj,int**s){
if(i==j)return;
Traceback(i,s[i][j],s);
Traceback(s[i][j]+1,j,s);
cout<<"三角剖分顶点:
V"<}
intWeight(inta,intb,intc){
returnweight[a][b]+weight[b][c]+weight[a][c];
}5-4数字三角形最短路径
#include#include#include"string.h"#defineMax101
usingnamespacestd;
intD[Max][Max];intnum;
intMaxSum(intnum){
inti,j;
for(i=num-1;i>=1;i--)
for(j=1;j<=i;j++){
D[i][j]=max(D[i+1][j],D[i+1][j+1])+D[i][j];
}
returnD[1][1];
}
intmain(intargc,charconst*argv[]){
inti,j;
cin>>num;
for(i=1;i<=num;i++)
for(j=1;j<=i;j++)
cin>>D[i][j];
cout<return0;}
5-2游艇租赁问题
#include
usingnamespacestd;
#defineN210
intcost[N][N];
intm[N];
intmain()
{
intn,i,j;
while(cin>>n)
{
for(i=1;ifor(j=i+1;j<=n;j++)
cin>>cost[i][j];
m[1]=0;
intmin;
for(i=2;i<=n;i++)
{
min=cost[1][i];
for(j=1;j<=i-1;j++)
{
if(cost[j][i]!
=0&&m[j]+cost[j][i]min=m[j]+cost[j][i];
}
m[i]=min;
}
cout<}
return0;
}
5-6合唱队形问题
#include
1.using namespace std;
2.
3.//用于保存子问题最优解的备忘录
4.typedef struct
5.{
6. int maxlen; //当前子问题最优解
7. int prev; //构造该子问题所用到的下一级子问题序号(用于跟踪输出最优队列)
8.}Memo;
9.
10.//用于递归输出Memo B中的解
11.void Display(int* A, Memo* M, int i)
12.{
13. if (M[i].prev == -1)
14. {
15. cout<16. return;
17. }
18. Display(A, M, M[i].prev);
19. cout<20.}
21.
22.//算法主要部分
23.void GetBestQuence(int* A, int n)
24.{
25. //定义备忘录 并作必要的初始化
26. Memo *B = new Memo[n]; //B[i]代表从A[0]到A[i]满足升序剔除部分元素后能得到的最多元素个数
27. Memo *C = new Memo[n]; //C[i]代表从A[i]到A[n-1]满足降序剔除部分元素后能得到的最多元素个数
28. B[0].maxlen = 1; //由于B[i]由前向后构造 初始化最前面的子问题 (元素本身就是一个满足升序降序的序列)
29. C[n-1].maxlen = 1; //同样C[i]由后向前构造
30. for (int i=0; i31. //用于在跟踪路径时终止递归或迭代(因为我们并不知道最终队列从哪里开始)
32. {
33. B[i].prev = -1;
34. C[i].prev = -1;
35. }
36.
37. for (i=1; i38. {
39. int max=1;
40. for (int j=i-1; j>=0; j--) //查看前面的子问题 找出满足条件的最优解 并且记录
41. {
42. if (A[j]max)
43. {
44. max = B[j].maxlen+1; //跟踪当前最优解
45. B[i].prev = j; //跟踪构造路径
46. }
47. }
48. B[i].maxlen = max; //构造最优解
49. }
50.
51. for (i=n-1; i>0; i--)
52. {
53. int max=1;
54. for (int j=i; j55. //否则我们得到的最优解始终为B[n-1]+C[n-1]
56. {
57. if (A[j]max) //比当前长度更长 记录并构造
58. {
59. max = C[j].maxlen+1;
60. C[i].prev = j;
61. }
62. }
63. C[i].maxlen = max;
64. }
65.
66. //遍历i 得到最大的B[i]+C[i]-1(-1是因为我们在B[i]和C[i]中 均加上了A[i]这个数 因此需要减去重复的)
67. int maxQ