算法分析与设计复习题及参考答案 联系客服

发布时间 : 星期日 文章算法分析与设计复习题及参考答案更新完毕开始阅读13b82668abea998fcc22bcd126fff705cc175cff

a

1

1

a.

b.

177.5(1,1,1,1,0,,0)

(1,1,1,1,0,0,1)

604

6012c. d.

60

35 35

(1,1,0,1,0,1,0)

60

12(1,1,1,1,0,0,1)在Q处获得该问题的最优解为,背包效益为170。即在背包中装入物品F、B、G、D、A时达1到最大效益,为170,重量为150。 19、求解子集和问题:对于集合S={1,2 ,6,8},求子集,要求该子集的元素之和d=9。 ①画出子集和问题的解空间树; ②该树运用回溯算法,写出依回溯算法遍历节点

的顺序; ③ 如果

S中有n个元素,指定d,用伪代码

描述求解子集和问题的回溯算法。 解答:满足要求0 0 0 0 1 1 0 0 1 1 1 1 1 0 1 0 ? ? Y Z ? ? P ê R X Q S T U V W ②遍历结点的顺序为:A B D

H P Q I R S E J T U K V W C F L X Y M Zê G N ? ?O ? ? ③用伪

的子集有[1,2,6], [1,8] ①解空间树如下:

代码描述算法如下: #include #define N 100 int as=0,t=0; int sum; void backtrackiter(int i,int s[],int n,int d,int sum) { if(i>n)

return; else { if(as==d) { t++; return; } sum-=s[i]; if(as+s[i]<=d) { as+=s[i]; backtrackiter(i+1,s,n,d,sum); as-=s[i]; } if(as+sum>=d) backtrackiter(i+1,s,n,d,sum); sum+=s[i]; } } 20、求解填字游戏问题:在3×3个方格的方阵中要填入数字1到N(N≥10)内的某9个数字,每个方格填一个整数,似的所有相邻两个方格内的两个整数之和为质数。试采用回溯法写出满足这个要求的一种数字填法的算法和满足这个要求的全部数字填法的算法。 解:为找到一个满足要求的9个数的填法,从还未填一个数开始,按某种顺序(如从小到大的顺序)每次在当前位置填入一个整数,然后检查当前填入的整数是否能满足要求。在满足要求的情况下,继续用同样的方法为下一方格填入整数。如果最近填入的整数不能满足要求,就改变填入的整数。如对当前方格试尽所有可能的整数,都不能满足要求,就得回退到前一方

格,并调整前一方格填入的整数。如此重复执行扩展、检查或调整、检查,直到找到一个满足问题要求的解,将解输出。 回溯法找一个解的算法: { int m=0,ok=1; int n=8; do{ if (ok) 扩展; else 调整; ok=检查前m个整数填放的合理性; } while ((!ok||m!=n)&&(m!=0)) if (m!=0) 输出解; else 输出无解报告; } 如果要找全部解,则在将找到的解输出后,应继续调整最后位置上填放的整数,试图去找下一个解。相应的算法如下: 回溯法找全部解的算法: { int m=0,ok=1;

int n=8; do{ if (ok) { if (m==n) { 输出解; 调整; } else 扩展; } else 调整; ok=检查前m个整数填放的合理性; } while (m!=0); }

21、试用动态规划算法实现最大子

矩阵和问题:求矩阵A的一个子矩阵,使其各元素之和为最大。 解:解答如下: int MaxSum2(int m,int n,int **a) { int sum=0; int *b=new int[n+1]; for(int i=1;i<=m;i++){ for(int k=1;k<=n;k++) b[k]=0; for(int j=i;j<=m;j++){ for(int k=1;k<=n;k++) b[k]+=a[j][k]; int max=MaxSum(n,b); if(max>sum) sum=max; } } return sum; } int MaxSum(int n,int *a) { int sum=0,b=0; for(int i=1;i<=n;i++){ if(b>0) b+=a[i]; else b=a[i]; if(b>sum) sum=b; } Return sum; }

i

22、试用回溯法解决下列整数变换问

题:关于整数的变换和定义如下:。对

nmnmfg于给定的两个

整数和,要求用最少的变换和变换次数将变为。 解:解答如下:

void compute() { k=1;

while(!search(1,n)){ k++; if(k>maxdep) break; init(); }; if(found) output(); else cout<<”No Solution!”<k) return false; for(int i=0;i<2;i++){ int n1=f(n,i);t[dep]=i; if(n1= =m||search(dep+1,n1)){ Found=true; Out(); return true; } return false; } 23、关于15谜问题。在一个4×4的方格的棋盘上,将数字1到15代表的15个棋子以任意的顺序置入各方格中,空出一格。要求通过有限次的移动,把一个给定的初始状态变成目标状态。移动的规则是:每次只能把空格周围的四格数字(棋子)中的任意一个移入空格,从而形成一个新的状态。为了有效的移动,设计了估值函数C(x),表示在结点x的状态下,没有到达目标状态下的正确位置的棋子的个数。 1请使用该估计函数,对图示的初始状态,给出使用分支限界方法转换到目标状态的搜索树。 1 2 4 1 2 3 4 5 6 3 7 5 6 7 8 9 10 12 8 9 10 11 12 13 14 11 15 13 14 15 初始状态 目标状态 解

1245637910128613141115124123412456375675637577910128910128910128131411151314111513141115123412341234567561275676549101289108910128131411151314111513141115123123456745678539101289101213141115131411151234123456787856239101291012151314111513141112341234123456856785678313910712910111291012131411151314151314111512341234567856782091011129101112131415131415