第五章报告+学期末总结
1. 对回溯算法的理解
回溯法也是一个寻求问题最优解的算法,本质是一种深度优先搜索算法的改进。
回溯法的基本思路是对于问题的可行解建立成树,搜索遍历每个节点并对其节点状态进行比较,在全部搜索完成后,自然的得到的是问题的最优解

关键:
1.回溯:回溯函数的设计有基本格式
void Backtrack(int t)//以深度优先的方式遍历第t层中的某棵子树 { if(t>n) { Output(x); return; } //遍历到叶子结点,返回 if (……) { x[t]=1; Backtrack(t+1); } //满足条件进入左子树 if (……) { x[t]=0; Backtrack(t+1); } //满足条件进入右子树 }//注意Backtrack(t+1)后要将Backtrack(t+1)前进入子树改变的条件还原
2.剪枝函数的设计:对于一些可以提前确定不可能是最优解的节点,设计这样的剪枝函数避免对他的搜索,以提高算法效率
分为约束函数(不满足约束条件)和界限函数(得不到最优解)
3.经典0-1背包问题代码:
#include<bits/stdc++.h> using namespace std; int n; double cmax,bestv=0,nowv=0,noww=0; struct P{ double w,v; }p[1000]; bool cmp(P p1,P p2){ return p1.v/p1.w > p2.v/p2.w ; } double bound(int t){ double cleft=cmax-noww,sum=nowv; while(t<=n && p[t].w<=cleft){ cleft-=p[t].w; sum+=p[t].v; t++; } if(t<=n) sum+=p[t].v/p[t].w*cleft; return sum ; } void bt(int t){ if(t>n){ if(bestv<nowv) bestv=nowv; } else{ if(noww+p[t].w<=cmax){ noww+=p[t].w; nowv+=p[t].v; bt(t+1); noww-=p[t].w; nowv-=p[t].v; } if(bound(t+1)>bestv){ bt(t+1); } } } int main(){ cin>>n>>cmax; for(int i=1;i<=n;i++) cin>>p[i].w>>p[i].v; sort(p,p+n,cmp); bt(1); cout<<bestv<<endl; return 0; }
2. 学习《算法分析与设计》课程的收获
本学期重点学习了分治法,二分搜索,动态规划算法,贪心算法和回溯法,经过本学期的学习,我对编程的算法设计有了初步的概念,了解了处理一些常规问题时可以使用的算法,策略和技巧;
通过对算法设计和分析的学习,我认识到,对于一些经典的问题,有许多经典的算法,这些是我们应该深入学习和掌握了解的,
在此基础上,去解决现实存在的更复杂的问题,往往需要对经典算法举一反三,并且不断地根据实际情况优化算法,
才能获得更低的时间复杂度和空间复杂的,而一个小于n^2的时间复杂度,是大部分问题所追求的。
学习分治,二分搜索算法:我明白了最基础的搜索查找算法,并且了解了递归调用的时间复杂度分析
学习动态规划算法:我了解了对于很多边计算边比较的问题,有这样一种算法可能使时间复杂度从n^3降低为n^2
学习贪心算法:我了解了对于大规模问题只要满足最优子结构性质和局部最优性质就可以从子问题开始设计一个最直接的算法直接求解
学习回溯法:我了解了对于“分层”的问题,可以做树的深度优先遍历,递归调用函数,搜索每个节点,比较得出最优解
3. 你在学习过程中曾遇到了哪些困难,希望老师或助教及时给予帮助。
对于动态规划算法,我时常不知道如何构建表格,不知道是一维表格合适还是二维表格合适,如果题目比较复杂,我很难决定用那些数据作为表的元素
比如0-1背包问题,如果不看书,我几乎不可能想出来m[i][j]中i代表背包剩余容量,j代表第j个装入的物品。
4. 你对本门课程的教学有哪些建议
暂无(老师很好,是我太菜 T_T)

浙公网安备 33010602011771号