算法导论第十五章-动态规划-Cpp代码实现
来源:互联网 发布:天狼星期货软件 编辑:程序博客网 时间:2024/04/30 11:46
算法导论第十五章-动态规划-Cpp代码实现。
实现了书中切钢条最大收益问题和经典算法最长公共子序列(LCS)的问题。
从递归,引出带备忘的自顶向下,自底向上等解法。
dynamic_programming.h
#pragma once/*************************************************Author:董小歪Date:2016-06-16Description:算法导论第十五章-动态规划-Cpp代码实现**************************************************/#ifndef DYNAMIC_PROGRAMMING_H#define DYNAMIC_PROGRAMMING_H#include <iostream>#include <vector>#include <algorithm>using namespace std;class Dynamic_Programming{public:int cut_rod(const vector<int> &p, int n);//递归算法int memorized_cut_rod(const vector<int>& p, int n);//带备忘的自顶向下法int bottom_up_cut_rod(const vector<int>& p, int n);//自底向上法vector<vector<int>> extended_button_up_cut_rod(const vector<int>& p, int n);//重构解void print_cut_rod_solution(const vector<int>& p, int n);//打印重构借vector<vector<int>> LCS_length(const vector<char>& vec1, const vector<char>& vec2);//LCSvoid print_LCS(const vector<vector<int>>& b, const vector<char>& vec1, int i, int j);//打印LCSprivate:int memorized_cut_aux(const vector<int>& p, int n, vector<int>& r);};#endif // !DYNAMIC_PROGRAMMING_H
dynamic_programming.cpp
#include "dynamic_programming.h"int Dynamic_Programming::cut_rod(const vector<int> &p, int n){if (n == 0)return 0;int q = INT_MIN;for (int i = 1; i <= n; ++i)q = max(q, p[i] + cut_rod(p, n - i));return q;}int Dynamic_Programming::memorized_cut_rod(const vector<int> &p, int n){vector<int> r(n + 1, INT_MIN);return memorized_cut_aux(p, n, r);}int Dynamic_Programming::memorized_cut_aux(const vector<int> &p, int n, vector<int>& r){if (r[n] >= 0)return r[n];int q = INT_MIN;if (n == 0)q = 0;else{for (int i = 1; i <= n; ++i)q = max(q, p[i] + memorized_cut_aux(p, n - i, r));}r[n] = q;return q;}int Dynamic_Programming::bottom_up_cut_rod(const vector<int>& p, int n){vector<int> r(n + 1, INT_MIN);r[0] = 0;for (int j = 1; j <= n; ++j){int q = INT_MIN;for (int i = 1; i <= j; ++i)q = max(q, p[i] + r[j - i]);r[j] = q;}return r[n];}vector<vector<int>> Dynamic_Programming::extended_button_up_cut_rod(const vector<int>& p, int n){vector<int> r(n + 1, 0), s(n + 1, 0);r[0] = 0;for (int j = 1; j <= n; ++j){int q = INT_MIN;for (int i = 1; i <= j; ++i){if (q < p[i] + r[j - i]){q = p[i] + r[j - i];s[j] = i;}}r[j] = q;}vector<vector<int>> ret;ret.push_back(r);ret.push_back(s);return ret;}void Dynamic_Programming::print_cut_rod_solution(const vector<int>& p, int n){vector<vector<int>> res = extended_button_up_cut_rod(p, n);for (int i = 0; i <= n; ++i){printf("r[%d] = %d, s[%d] = %d\n", i, res[0][i], i, res[1][i]);}}vector<vector<int>> Dynamic_Programming::LCS_length(const vector<char>& vec1, const vector<char>& vec2){int m = vec1.size(), n = vec2.size();vector<vector<int>> b(m + 1, vector<int>(n + 1, 0));vector<vector<int>> c(m + 1, vector<int>(n + 1, 0));for (int i = 1; i <= m; ++i){for (int j = 1; j <= n; ++j){if (vec1[i - 1] == vec2[j - 1]){c[i][j] = c[i - 1][j - 1] + 1;b[i][j] = 2;}else if (c[i - 1][j] >= c[i][j - 1]){c[i][j] = c[i - 1][j];b[i][j] = 3;}else{c[i][j] = c[i][j - 1];b[i][j] = 1;}}}return b;}void Dynamic_Programming::print_LCS(const vector<vector<int>>& b, const vector<char>& vec1, int i, int j){if (i == 0 || j == 0)return;if (b[i][j] == 2){print_LCS(b, vec1, i - 1, j - 1);cout << vec1[i-1];}else if (b[i][j] == 3)print_LCS(b, vec1, i - 1, j);elseprint_LCS(b, vec1, i, j - 1);}
测试代码:
main_entrance.cpp
#include "dynamic_programming.h"int main(){vector<int> p = { 0,1,5,8,9,10,17,17,20,24,30 };printf("钢条的价格表:\n长度i:\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\n");printf("价格pi:%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n\n",p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10]);Dynamic_Programming dp;cout << "递归算法:长度为4的钢条最大收益为:" << dp.cut_rod(p, 4) << endl;cout << "递归算法:长度为10的钢条最大收益为:" << dp.cut_rod(p, 10) << endl;cout << "自顶向下:长度为4的钢条最大收益为:" << dp.memorized_cut_rod(p, 4) << endl;cout << "自顶向下:长度为10的钢条最大收益为:" << dp.memorized_cut_rod(p, 10) << endl;cout << "自底向上:长度为4的钢条最大收益为:" << dp.bottom_up_cut_rod(p, 4) << endl;cout << "自底向上:长度为10的钢条最大收益为:" << dp.bottom_up_cut_rod(p, 10) << endl;cout << "自底向上切割的方法,长度10内的结果,r[i]表示最大收益,s[i]表示当前最大收益下的第一段切割长度:" << endl; dp.print_cut_rod_solution(p, 10);vector<char> vec1 = { 'A','B','C','B','D','A','B' };vector<char> vec2 = { 'B','D','C','A','B','A' };cout << endl << "串1序列是:";for (auto ch : vec1)cout << ch;cout << endl << "串2序列是:";for (auto ch : vec2)cout << ch;cout << endl << "最长公共子序列是:" << endl;dp.print_LCS(dp.LCS_length(vec1, vec2), vec1, vec1.size(), vec2.size());cout << endl;system("pause");}
测试结果:
0 0
- 算法导论第十五章-动态规划-Cpp代码实现
- 算法导论学习笔记-第十五章-动态规划
- 算法导论笔记——第十五章 动态规划
- 算法导论动态规划实现
- 算法导论第十五章习题15.1-1c++代码实现
- 算法导论第十五章习题15.4-4c++代码实现
- 算法导论第二章-算法基础-Cpp代码实现
- 算法导论第十六章-贪心算法-Cpp代码实现
- 算法导论第十五章动态规划--工厂装配线c++代码实现
- 算法导论第十五章--动态规划的变形(做备忘录的递归算法)
- 算法导论 第十五章:动态规划之棒的切割(Rod Cutting)
- 算法导论第六章-堆排序-Cpp代码实现
- 算法导论第七章-快速排序-Cpp代码实现
- 算法导论第八章-线性时间排序-Cpp代码实现
- 算法导论第四章-分治策略-Cpp代码实现
- 算法导论第十章-基本数据结构-Cpp代码实现
- 算法导论第十二章-二叉搜索树-Cpp代码实现
- 算法导论第十三章-红黑树-Cpp代码实现
- ORA-01200: actual file size of 533 is smaller than correct size of 640 blocks
- 将Mercurial整合到Flask项目中
- 自定义View之路——Canvas(save,restore,translate,rotate)
- removeCallbacksAndMessages(null)的含义
- mysql 模拟rownum 并做一些简单适用的操作
- 算法导论第十五章-动态规划-Cpp代码实现
- 使用PopupWindow配合EditText制作模糊搜索
- 问题咨询
- 简述HLS,HTTP,RTSP,RTMP协议的区别
- Handler消息传递机制
- 485 繁琐问题,烦烦烦
- ndroid studio修改项目名,模块名,包名
- Android中使用ImageView控件显示网络图片
- JZOJ.1166 树中点对距离