144
社区成员
发帖
与我相关
我的任务
分享《算法设计与分析》第三章 动态规划算法 作业
1. 概括第三章学习内容,总结第三章学习心得。
第三章主要介绍了动态规划算法相关对的知识和概念。以经典的最优化问题为例子,讲述掌握动态规划算法的背景知识、基本要素以及求解过程,分析了最优化问题的相关知识背景以及求解过程。使用动态规划算法对0-1背包问题、最长公共子序列问题、矩阵连乘问题等经典问题求解,详细分析了求解过程,对动态规划算法的整体设计有了更深入的了解和掌握。
本章知识结构如图所示:

2.以{0-1}背包问题的动态规划算法设计为例,陈述对伪多项式时间复杂度概念的理解。
多项式时间算法表示算法的复杂度与问题输入规模呈多项式关系,而伪多项式时间算法复杂度表示算法的复杂度与输入规模呈指数关系,与输入的数值大小呈多项式关系。
伪多项式时间复杂度其实从本质上来讲,是将其中的部分非多项式元素用多项式形式替换,从表达式格式上看来,属于多项式表达式,但是本质上来看是非多项式。
例如在0-1背包问题的动态规划算法中,时间复杂度为O(nc),当c较小时候,复杂度呈现多项式复杂度特性,而当c很大的时候,例如c>2n时,其时间复杂度将会称为O(n2n)。
3. 算法实验1:采用动态规划算法计算任意两个字符序列的最长公共子序列;总结实验出现问题及解决方法。
#include<stdio.h>
#include<string.h>
#include<stream.h>
#define N 50
char str1[N];
char str2[N];
int c[N][ N];
int b[N][ N];
void lcs(int lenght1, int lenght2){
if(lenght1 == 0 || lenght2 == 0){
return;
}
if(b[lenght1][lenght2] == 1){
lcs (lenght1-1,lenght2-1);
cout<<str1[lenght1-1];
}
else if(b[lenght1][lenght2] == 2){
lcs (lenght1-1,lenght2);
}else{
lcs (lenght1,lenght2-1);
}
}
void LCS_Length(char str1[], char str2[]){
int str1_lenght, str2_lenght;
str1_lenght = strlen(str1);
str2_lenght = strlen(str2);
if(str1_lenght == 0 || str2_lenght == 0){
cout<< "No sub seqence";
return;
}
int i, j;
for(i = 0; i <= str1_lenght; i++){
c[i][0] = 0;
}
for(j = 0; j <= str2_lenght; j++){
c[0][j] = 0;
}
for(i = 1; i <= str1_lenght; i++){
for(j = 1; j <= str2_lenght; j++){
if (str1[i-1] == str2[j-1]){
c[i][j] = c[i-1][j-1] + 1;
b[i][j] = 1;
}
else if(c[i-1][j] > c[i][j-1]){
c[i][j] = c[i-1][j];
b[i][j] = 2;
}
else{
c[i][j] = c[i][j-1];
b[i][j] = 3;
}
}
}
if(c[str1_lenght][str2_lenght] <= 0){
cout<<"没有公共子序列";
return;
}
cout<< c[str1_lenght][str2_lenght];
lcs (str1_lenght,str2_lenght);
cout<<endl;
}
int main(){
cout<<"第一个字符串序列:";
cin>>str1;
cout<<"第二个字符串序列:";
scin>>str2;
LCS_Length(str1,str2);
return 0;
}
参照教材算法主体,在本算法实现过程中,遇到的主要问题是全局变量的设计,全局变量要在主函数和递归函数中都要调用,所以用全局变量模式设计。
4. 算法实验2:利用动态规划算法编程求解矩阵连乘问题;总结实验出现问题及解决方法。
#include<iostream>
#include<iomanip>
#include<cstring>
using namespace std;
const int sz= 20;
void MatrixChain(int *p, int m[sz][sz], int s[sz][sz], int length) {
for (int i = 1;i<= length; i++) {
m[i][i] = 0;
}
for (int r = 2; r <= length; r++) {
for (int i = 1; i <= length;i++) {
int j = i + r - 1;
m[i][j] = m[i + 1][j]+ p[i - 1] * p[i] * p[j];
s[i][j] = i;
for (int k = i + 1; k < j; k++) {
int t = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (t < m[i][j]) {
m[i][j] = t;
s[i][j] = k;
}
}
}
}
}
void printMatrix(int m[sz][sz] ,int length) {
for (int i = 1; i <= length; i++) {
for (int j = 1; j <= length; j++) {
cout << setw(6) << setfill(' ') << m[i][j] << " ";
}
cout << endl;
}
}
void printresult(int s[sz][sz], int i, int j) {
if (i == j)
{
cout << "A" << i;
}
{
cout << "(";
printresult(s, i, s[i][j]);
printresult(s, s[i][j] + 1, j);
cout << ")";
}
}
int main() {
int n;
int p[sz], m[sz][sz], s[sz][sz];
memset(p, 0, sizeof(p));
memset(m, 0, sizeof(m));
memset(s, 0, sizeof(s));
cout << "请输入矩阵的个数:" ;
cin >> n;
for (int i = 0; i <= n; i++) {
cout << "请输入"<<(i+1)<<"个矩阵第一维的下标(也就是第"<<i<<" 个矩阵第二维的下标):";
cin >> p[i];
}
cout << "你输入的矩阵为:" << endl;
for (int i = 0; i <n; i++) {
cout << "A" << (i + 1) << "[" << p[i] << "]"<< "[" << p[i + 1] << "] ";
}
cout << endl;
cout << "m矩阵为:" << endl;
MatrixChain(p, m, s, n);
printMatrix(m, n);
cout << "s矩阵为:" << endl;
printMatrix(s, n);
printresult(s, 1, n);
system("pause");
return 0;
}
在这个算法的实验过程中,遇到的困难是加括号输出的实现,采用递归的方法实现该问题。