算法设计与分析 期末考点
简答题
分治法和动态规划法基本思想及其两种方法的异同
对于一个规模为n的问题:若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这就是分治法
动态规划的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。
在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。
相同点在于,二者要求原问题都具有最优子结构性质,都是将原问题分而治之,分解成若干个规模较小的子问题,然后将子问题的解合并,形成原问题的解
区别在于,分治法将分解后的子问题看成相互独立的,通常用递归来做,动态规划法将分解后的子问题理解为相互间有练习,有重叠部分,需要记忆,通常用迭代来做
回溯法和分支限界法的基本思想和两种方法的异同点
1.回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支界限法的求解目标是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解
2.回溯法以深度优先的方式搜索解空间树,而分支界限法以广度优先或以最小耗费优先的方式搜索解空间树
算法设计
动态规划:
- 实现最大子矩阵问题,取m行n列的子矩阵,怎么取能使矩阵各元素和最大
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;
}
回溯法解决整数变换问题
给定两个整数集合M,N,使用给出的两个函数,用最少的转换次数将整数集M转换成N
两个函数是f( i ) = 3*i和g( i )=floor(i/2)
void compute(){
k = 1;
while(!search(1,n)){
k++;
if(k>maxdep) break;
init();