算法第三章作业
1. 你对动态规划算法的理解(2分)
我认为动态规划的特点是在深搜的基础上优化,也就是对相同的子问题上不再进行重复的求解,求解过的子问题可以直接翻记录得到答案。
2. 分别列出编程题1、2的递归方程(2分)
1)单调递增最长子序列
递归方程:dis[i] = max(dis[i], dis[j]+1) (1 <= i, 0 <= j < i)
代码展示:
1 int MIESS(int *a, int n) { 2 int *dis = new int[n]; 3 int max_len = 1; 4 for (int i = 0; i < n; ++i) { 5 dis[i] = 1; //序列中的每一个数字都是一个新的起点,所以用数组来存储distance 6 for (int j = 0; j < i; ++j) { 7 /*将该数字与前面的数组一一进行比较判断, 8 但是因为有了dis的帮助,所以我们不需要再进行判断了, 9 dis[前面的i]已经帮我们记录了之前的运算*/ 10 if (a[i] >= a[j] && dis[i] < dis[j] + 1) { 11 // && dis[i] < dis[j] + 1这个条件也需要 12 //是因为中间有些序列是比较短的,只需要取这些距离中最长的加一 13 dis[i] = dis[j] + 1; 14 } 15 } 16 if (dis[i] > max_len) { 17 //答案有可能存在序列中的某一个位置所以需要一直记录着 18 max_len = dis[i]; 19 } 20 } 21 delete [] dis; 22 return max_len; 23 }
2)租游艇问题
递归方程:a[1][i] = max(a[1][j], a[j][i]+a[1][i]) (2 <= i <= n, 1 <= j < i)
代码展示:
1 int Rent_yachts(int a[200][201], int n) { 2 /*虽然是N方的时间复杂度,但是通过动归的思想每个循环体中 3 就只有一行代码(比较并赋值,赋值即记录)*/ 4 for (int i = 2; i <= n; ++i) { 5 for (int j = 1; j <= i - 1; ++j) { //求出到达每个站的最省钱方案 6 a[1][i] = (a[1][j] + a[j][i] < a[1][i] ? a[1][j] + a[j][i] : a[1][i]); 7 } 8 } 9 return a[1][n]; 10 }
3. 说明结对编程情况(1分)
我和小伙伴江元发一起对很多问题都进过探讨,在思想的碰撞中我们收获良多,也希望能保持这样良好的状态继续共同进步!!