动态规划算法实验报告
动态规划实验报告

动态规划实验报告动态规划实验报告一、引言动态规划是一种常用的算法设计方法,广泛应用于计算机科学和运筹学等领域。
本实验旨在通过实际案例,探究动态规划算法的原理和应用。
二、实验背景动态规划算法是一种通过将问题分解为子问题,并存储子问题的解来解决复杂问题的方法。
它通常适用于具有重叠子问题和最优子结构性质的问题。
三、实验目的1. 理解动态规划算法的基本原理;2. 掌握动态规划算法的实现方法;3. 分析动态规划算法在实际问题中的应用。
四、实验过程本实验选择了经典的背包问题作为案例进行分析。
背包问题是一个组合优化问题,给定一个背包的容量和一系列物品的重量和价值,如何选择物品放入背包,使得背包中物品的总价值最大化。
1. 确定状态在动态规划算法中,状态是问题的关键。
对于背包问题,我们可以将状态定义为背包的容量和可选择的物品。
2. 确定状态转移方程状态转移方程是动态规划算法的核心。
对于背包问题,我们可以定义一个二维数组dp[i][j],表示在背包容量为j的情况下,前i个物品的最大总价值。
则状态转移方程可以表示为:dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])其中w[i]表示第i个物品的重量,v[i]表示第i个物品的价值。
3. 初始化边界条件在动态规划算法中,边界条件是必不可少的。
对于背包问题,边界条件可以定义为当背包容量为0时,无论物品如何选择,总价值都为0。
4. 递推求解根据状态转移方程和边界条件,我们可以通过递推的方式求解问题。
具体步骤如下:- 初始化dp数组;- 逐行逐列计算dp数组的值,直到得到最终结果。
五、实验结果与分析通过实验,我们得到了背包问题的最优解。
同时,我们还可以通过分析dp数组的取值,了解到每个状态下的最优选择。
这为我们提供了在实际问题中应用动态规划算法的思路。
六、实验总结本实验通过对动态规划算法的实际案例进行分析,深入理解了动态规划算法的原理和应用。
动态规划建模实验报告

一、实验背景动态规划是一种重要的算法设计方法,它通过将复杂问题分解为若干个相互重叠的子问题,并存储子问题的解,从而避免重复计算,有效地解决一系列优化问题。
本实验旨在通过具体案例,加深对动态规划算法的理解和应用。
二、实验目的1. 掌握动态规划的基本概念和原理。
2. 熟悉动态规划建模的过程和步骤。
3. 提高运用动态规划解决实际问题的能力。
三、实验内容本次实验选取了“背包问题”作为案例,旨在通过解决背包问题,加深对动态规划算法的理解。
四、实验步骤1. 问题分析背包问题是一个经典的组合优化问题,描述为:给定一个容量为C的背包和N件物品,每件物品有价值和重量两个属性,求如何将物品装入背包,使得背包中的物品总价值最大,且不超过背包的容量。
2. 模型建立(1)定义状态:设dp[i][j]表示在前i件物品中选择若干件装入容量为j的背包所能获得的最大价值。
(2)状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i-1][j-weights[i]] + values[i]),其中weights[i]表示第i件物品的重量,values[i]表示第i件物品的价值。
(3)边界条件:dp[0][j] = 0,表示没有物品时,背包价值为0。
3. 编程实现使用C语言编写动态规划程序,实现背包问题的求解。
4. 结果分析(1)运行程序,输入背包容量和物品信息。
(2)观察输出结果,包括物品选择的列表和最大价值。
(3)验证结果是否正确,与理论分析进行对比。
五、实验结果与分析1. 实验结果:通过编程实现,成功求解了背包问题,并得到了最大价值。
2. 结果分析:(1)动态规划算法在解决背包问题时,有效地避免了重复计算,提高了求解效率。
(2)实验结果表明,动态规划算法能够有效地解决背包问题,为实际应用提供了有力支持。
六、实验总结1. 动态规划是一种重要的算法设计方法,具有广泛的应用前景。
2. 动态规划建模过程中,关键在于正确地定义状态和状态转移方程。
动态规划实验报告心得

一、实验背景动态规划是一种重要的算法设计方法,广泛应用于解决优化问题。
本次实验旨在通过实际操作,加深对动态规划算法的理解,掌握其基本思想,并学会运用动态规划解决实际问题。
二、实验内容本次实验主要包括以下几个内容:1. 动态规划算法概述首先,我们对动态规划算法进行了概述,学习了动态规划的基本概念、特点、应用领域等。
动态规划是一种将复杂问题分解为若干个相互重叠的子问题,并存储已解决子问题的解,以避免重复计算的方法。
2. 矩阵连乘问题矩阵连乘问题是动态规划算法的经典问题之一。
通过实验,我们学会了如何将矩阵连乘问题分解为若干个相互重叠的子问题,并利用动态规划方法求解。
实验过程中,我们分析了问题的最优子结构、子问题的重叠性,以及状态转移方程,从而得到了求解矩阵连乘问题的动态规划算法。
3. 0-1背包问题0-1背包问题是另一个典型的动态规划问题。
在实验中,我们学习了如何将0-1背包问题分解为若干个相互重叠的子问题,并利用动态规划方法求解。
实验过程中,我们分析了问题的最优子结构、子问题的重叠性,以及状态转移方程,从而得到了求解0-1背包问题的动态规划算法。
4. 股票买卖问题股票买卖问题是动态规划在实际应用中的一个例子。
在实验中,我们学习了如何将股票买卖问题分解为若干个相互重叠的子问题,并利用动态规划方法求解。
实验过程中,我们分析了问题的最优子结构、子问题的重叠性,以及状态转移方程,从而得到了求解股票买卖问题的动态规划算法。
三、实验心得1. 动态规划算法的思维方式通过本次实验,我深刻体会到了动态规划算法的思维方式。
动态规划算法的核心是将复杂问题分解为若干个相互重叠的子问题,并存储已解决子问题的解。
这种思维方式有助于我们更好地理解和解决实际问题。
2. 状态转移方程的重要性在动态规划算法中,状态转移方程起着至关重要的作用。
它描述了子问题之间的关系,是求解问题的关键。
通过本次实验,我学会了如何分析问题的最优子结构,以及如何建立合适的状态转移方程。
实验报告:动态规划01背包问题)范文(最终五篇)

实验报告:动态规划01背包问题)范文(最终五篇)第一篇:实验报告:动态规划01背包问题)范文XXXX大学计算机学院实验报告计算机学院2017级软件工程专业班指导教师学号姓名2019年 10月 21日成绩课程名称算法分析与设计实验名称动态规划---0-1 背包问题①理解递归算法的概念实验目的②通过模仿0-1 背包问题,了解算法的思想③练习0-1 背包问题算法实验仪器电脑、jdk、eclipse 和器材实验:0-1 背包算法:给定N 种物品,每种物品都有对应的重量weight 和价值 value,一个容量为maxWeight 的背包,问:应该如何选择装入背包的物品,使得装入背包的物品的总价值最大。
(面对每个物品,我们只有拿或者不拿两种选择,不能选择装入物品的某一部分,也实验不能把同一个物品装入多次)代码如下所示:内 public classKnapsackProblem {容 /**、上 * @paramweight 物品重量机 * @paramvalue 物品价值调 * @parammaxweight背包最大重量试程 *@return maxvalue[i][j] 中,i 表示的是前 i 个物品数量,j 表示的是重量序 */、publicstaticint knapsack(int[]weight , int[]value , intmaxweight){程序运行结果实验内 intn =;包问题的算法思想:将前 i 个物品放入容量容为 w 的背包中的最大价值。
有如下两种情况:、①若当前物品的重量小于当前可放入的重量,便可考虑是上否要将本件物品放入背包中或者将背包中的某些物品拿出机来再将当前物品放进去;放进去前需要比较(不放这个物调品的价值)和(这个物品的价值放进去加上当前能放的总试重量减去当前物品重量时取i-1 个物品是的对应重量时候程的最高价值),如果超过之前的价值,可以直接放进去,反序之不放。
动态规划问题实验报告(3篇)

第1篇一、实验目的本次实验旨在让学生理解动态规划算法的基本概念,掌握动态规划解决问题的基本思想和步骤,并能运用动态规划算法解决实际问题。
通过实验,学生应能够:1. 理解动态规划算法的概念及其应用领域。
2. 掌握动态规划的基本思想和解决问题的基本步骤。
3. 学习动态规划算法设计策略,并能够运用到实际问题中。
4. 通过实际编程,提高编程能力和问题解决能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发环境:PyCharm三、实验内容本次实验选择了三个典型的动态规划问题进行实践:1. 最长公共子序列问题2. 矩阵连乘问题3. 剪绳子问题四、实验步骤1. 最长公共子序列问题(1)问题描述:给定两个序列X和Y,找出X和Y的最长公共子序列。
(2)算法设计:- 使用二维数组dp[i][j]表示X的前i个字符和Y的前j个字符的最长公共子序列的长度。
- 初始化dp[0][j] = 0和dp[i][0] = 0。
- 对于i > 0和j > 0,如果X[i-1] == Y[j-1],则dp[i][j] = dp[i-1][j-1] + 1;否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
(3)代码实现:```pythondef longest_common_subsequence(X, Y):m, n = len(X), len(Y)dp = [[0] (n + 1) for _ in range(m + 1)]for i in range(1, m + 1):for j in range(1, n + 1):if X[i - 1] == Y[j - 1]:dp[i][j] = dp[i - 1][j - 1] + 1else:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])return dp[m][n]```2. 矩阵连乘问题(1)问题描述:给定n个矩阵A1, A2, ..., An,其中Ai与Ai-1是可乘的,i = 1, 2, ..., n-1。
动态规划算法实验报告

南京信息工程大学滨江学院实验(实习)报告1.实验目的动态规划通常用来求解最优化问题。
通过本次实验掌握动态规划算法。
通过矩阵连乘问题和0-1背包问题实现动态规划算法。
学会刻画问题的最优结构特征,并利用最优化问题具有的重叠子问题性质,对每个子问题求解一次,将解存入表中,当再次需要这个子问题时直接查表,每次查表的代价为常量时间。
2.实验内容及分析设计过程1.矩阵链乘法问题矩阵链乘法问题可描述如下:给定个矩阵的链,矩阵的规模为,求完全括号方案,使得计算乘积所需的标量乘法次数最少。
令m[i,j]表示计算矩阵所需标量乘法次数的最小值,那么,原问题的最优解计是m[1,n]。
最小代价括号化方案的递归求解公式为采用自底向上表格法代替上述递归算法来计算最优代价。
为了实现自底向上方法,我们必须确定计算m[i,j]时需要访问哪些其他表项。
上述公式显示,j-i+l 个矩阵链相乘的最优计算代价m[i,j] 只依赖于那些少于j-i+l 个矩阵链相乘的最优计算代价。
因此,算法应该按长度递增的顺序求解矩阵链括号化问题,并按对应的顺序填写表m。
对如下输入A1 A2 A3 A4 A5 A630⨯35 35⨯15 15⨯5 5⨯10 10⨯20 20⨯25程序运行结果为2.背包问题给定n 个重量为价值为的物品和一个承重为W 的背包。
求这些物品中最有价值的一个子集,并且要能装到背包中。
设V[i,j]是能够放进承重量为j 的背包的前i 个物品中最有价值子集的总价值。
则递推关系为初始条件V[0,j]=0(j>=0),V[i,0]=0(i>=0) 我们的目标是求V[n ,W]。
递归式给出了V[i,j]的计算顺序,V[i,j]只依赖与前一行的那些项。
故可以逐行计算V[i,j].对于物品数量n=5,w[n]={2,2,6,5,4},v[n]={6,3,5,4,6},背包总重量c=10 程序运行结果为3. 实验小结通过本次实验加深了我对动态规划算法的理解。
动态规划实验报告摘要(3篇)

第1篇本实验报告针对动态规划算法进行深入研究和实践,旨在通过一系列实验,加深对动态规划思想、基本原理及实际应用的理解。
实验内容涵盖了动态规划算法的多个经典问题,包括找零钱问题、独立任务最优调度问题、最长公共子序列问题、矩阵连乘问题、剪绳子问题以及0-1背包问题等。
一、实验目的1. 理解动态规划算法的概念,掌握动态规划的基本思想和解决问题的基本步骤。
2. 学习动态规划算法设计策略,提高算法设计能力。
3. 通过实际案例,体会动态规划算法在解决实际问题中的应用价值。
二、实验内容与步骤1. 找零钱问题实验要求设计一个动态规划算法,对给定面值的硬币组合,计算出所有可能找零方式的硬币个数。
通过实验,掌握了动态规划算法的基本原理,并熟悉了动态规划在解决组合优化问题中的应用。
2. 独立任务最优调度问题实验要求设计一个动态规划算法,使得两台处理机处理完n个作业的时间最短。
通过实验,了解了动态规划在解决调度问题中的应用,并掌握了多阶段决策问题的求解方法。
3. 最长公共子序列问题实验要求找出两个序列的最长公共子序列。
通过实验,学习了动态规划在解决序列匹配问题中的应用,并掌握了如何通过动态规划算法优化问题求解过程。
4. 矩阵连乘问题实验要求确定计算矩阵连乘积的计算次序,使得所需数乘次数最少。
通过实验,了解了动态规划在解决矩阵连乘问题中的应用,并掌握了如何通过动态规划算法优化计算过程。
5. 剪绳子问题实验要求将一根绳子剪成m段,使得各段乘积最大。
通过实验,掌握了动态规划在解决资源分配问题中的应用,并学会了如何通过动态规划算法找到最优解。
6. 0-1背包问题实验要求用动态规划算法解决0-1背包问题。
通过实验,了解了动态规划在解决背包问题中的应用,并掌握了如何通过动态规划算法优化问题求解过程。
三、实验结果与分析通过对以上问题的动态规划算法实现,实验结果表明:1. 动态规划算法能够有效地解决组合优化问题、调度问题、序列匹配问题、矩阵连乘问题、资源分配问题以及背包问题等。
动态规划实验报告

动态规划实验报告《动态规划实验报告》动态规划是一种重要的算法设计技术,它在解决许多实际问题中具有广泛的应用。
本实验报告将介绍动态规划算法的基本原理,并通过一个实际问题的求解过程来展示其应用效果。
首先,我们来了解一下动态规划的基本原理。
动态规划是一种将原问题分解为子问题来求解的方法,它通常用于求解最优化问题。
动态规划算法的核心思想是将原问题分解为若干个子问题,然后通过求解子问题的最优解来得到原问题的最优解。
为了避免重复计算子问题,动态规划算法通常采用记忆化搜索或者自底向上的方式来进行计算。
接下来,我们将通过一个实际问题来展示动态规划算法的应用效果。
假设我们有一组数字,我们希望找到其中的一个子序列,使得这个子序列的和最大。
这个问题可以通过动态规划算法来求解,具体的求解过程如下:1. 定义状态:我们定义一个状态数组dp,其中dp[i]表示以第i个数字结尾的子序列的最大和。
2. 状态转移方程:我们可以通过以下状态转移方程来求解dp数组:dp[i] = max(dp[i-1] + nums[i], nums[i]),其中nums[i]表示第i个数字。
3. 初始状态:我们将dp数组的初始状态设为dp[0] = nums[0]。
4. 求解最优解:最终的最优解即为dp数组中的最大值。
通过以上求解过程,我们可以得到原问题的最优解,即最大子序列的和。
这个实例展示了动态规划算法在实际问题中的应用效果,通过合理的状态定义和状态转移方程,我们可以高效地求解复杂的最优化问题。
综上所述,动态规划算法是一种重要的算法设计技术,它在解决最优化问题中具有广泛的应用。
通过合理的状态定义和状态转移方程,我们可以高效地求解复杂的实际问题。
希望本实验报告能够帮助读者更好地理解动态规划算法的基本原理和应用方法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
动态规划算法实验报告————————————————————————————————作者: ————————————————————————————————日期:实验标题1、矩阵连乘2、最长公共子序列3、最大子段和4、凸多边形最优三角剖分5、流水作业调度6、0-1背包问题7、最优二叉搜索树实验目的掌握动态规划法的基本思想和算法设计的基本步骤。
实验内容与源码1、矩阵连乘#include<iostream>#include<cstdlib>using namespace std;const int size=4;//ra,ca和rb,cb分别表示矩阵A和B的行数和列数void matriMultiply(int a[][4],int b[][4],int c[][4],int ra,intca,int rb,int cb){if(ca!=rb) cerr<<"矩阵不可乘";for(int i=0;i<ra;i++)for(int j=0;j<cb;j++){int sum=a[i][0]*b[0][j];for(int k=1;k<ca;k++)sum+=a[i][k]*b[k][j];c[i][j]=sum;}}voidMatrixChain(int*p,int n,int m[][4],int s[][4]){for(int i=1;i<=n;i++) m[i][i]=0;//对角线for(int r=2;r<=n;r++)//外维for(int i=1;i<=n-r+1;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 Traceback(int i,intj,ints[][4]){if(i==j){cout<<"A"<<i;}elseif(i+1==j){cout<<"(A"<<i<<"A"<<j<<")";}else{cout<<"(";Traceback(i,s[i][j],s);Traceback(s[i][j]+1,j,s);cout<<")";}}int main(){int w;cout<<"矩阵个数:";cin>>w;intp[w],s[w][w];cout<<"输入矩阵A1维数:";cin>>p[0]>>p[1];for(inti=2 ;i<=w ; i++){int m= p[i-1];cout<<"输入矩阵A"<<i<<"维数:";cin>>p[i-1]>>p[i];if(p[i-1]!=m){cout<<endl<<"维数不对,矩阵不可乘!"<<endl;exit(1);}}Traceback(1,w,s);return 0;}运行结果2、最长公共子序列#include<cstring>#include<iostream>#define N 100using namespace std;//str1存储字符串x,str2存储字符串ychar str1[N],str2[N];//lcs存储最长公共子序列charlcs[N];//c[i][j]存储str1[1...i]与str2[1...j]的最长公共子序列的长度int c[N][N];//flag[i][j]==0为str1[i]==str2[j]//flag[i][j]==1为c[i-1][j]>=s[i][j-1]//flag[i][j]==-1为c[i-1][j]<s[i][j-1]int flag[N][N];//求长度intLCSLength(char *x, char*y){inti,j;//分别取得x,y的长度intm = strlen(x);int n = strlen(y);for(i=1;i<=m;i++)c[i][0] = 0;for(i=0;i<=n;i++)c[0][i] = 0;for(i=1;i<=m;i++)for(j=1;j<=n;j++){if(x[i-1]==y[j-1]){c[i][j]= c[i-1][j-1]+1;flag[i][j] = 0;}elseif(c[i-1][j]>=c[i][j-1]){c[i][j]= c[i-1][j];flag[i][j] =1;}else{c[i][j]= c[i][j-1];flag[i][j] = -1;}}returnc[m][n];}//求出最长公共子序列char*getLCS(char *x, char *y,intlen,char *lcs) {int i = strlen(x);int j = strlen(y);while(i&&j){if(flag[i][j]==0){lcs[--len] = x[i-1];i--;j--;}else if(flag[i][j]==1)i--;elsej--;}returnlcs;}intmain(){int i;cout<<"请输入字符串x:"<<endl;cin>>str1;cout<<"请输入字符串y:"<<endl;cin>>str2;intlcsLen= LCSLength(str1,str2);cout<<"最长公共子序列长度:"<<lcsLen<<endl;char*p =getLCS(str1,str2,lcsLen,lcs);cout<<"最长公共子序列为:";for(i=0;i<lcsLen;i++)cout<<lcs[i]<<" ";return0;}运行结果3、最大子段和//分治法求最大子段和#include<iostream>using namespace std;int MaxSubSum(int *a,int left,int right){intsum=0;if(left==right) sum=a[left]>0?a[left]:0;else{int center =(left+right)/2;//最大子段和在左边intleftsum=MaxSubSum(a,left,center);//最大子段和在右边int rightsum=MaxSubSum(a,center+1,right);//最大子段和在中间int s1=0;intlefts=0;for(inti=center;i>=left;i--){lefts+=a[i];if(lefts>s1) s1=lefts;}int s2=0;int rights=0;for(int i=center+1;i<=right;i++) {rights+=a[i];if(rights>s2)s2=rights;}sum=s1+s2;//前后子段和相加//判断最大子段和if(sum>leftsum)sum=leftsum;if(sum>rightsum) sum=rightsum;}return sum;}intMaxSum(int*a,int n){return MaxSubSum(a,1,n-1);}int main(){int a[8]={2,-3,-5,4,1,7,1,-5};cout<<"最大子段和为:"<<MaxSum(a,8);return0;}//动态规划法#include<iostream>usingnamespacestd;int MaxSum(int *a,int n){int sum=0,b=0;for(int i=1;i<n;i++)//此处不能=n,{if(b>0) b+=a[i];else b=a[i];if(b>sum)sum=b;}return sum;}intmain(){inta[8]={2,-3,-5,4,1,7,1,-5};cout<<"最大子段和为:"<<MaxSum(a,8);return 0;}运行结果4、凸多边形最优三角剖分#include<iostream>#include<cmath>#include<cstdlib>#define N 50using namespace std;struct point{int x;int y;};int distance(pointX, point Y)//两点距离{int dis =(Y.x-X.x)*(Y.x-X.x)+ (Y.y-X.y)*(Y.y-X.y);return (int)sqrt(dis);}intw(point a, point b, point c)//权值{return distance(a,b)+ distance(b,c) +distance(a,c); }bool JudgeInput()//判断是否能构成凸多边形{point*v;//记录凸多边形各顶点坐标int *total; //记录坐标在直线方程中的值int m,a,b,c;cout<<"请输入凸多边形顶点个数:";cin>>m;int M= m-1;for(inti=0; i<m;i++){cout<<"输入顶点v"<<i<<"的坐标:";cin>>v[i].x>>v[i].y;}//根据顶点坐标判断是否能构成一个凸多边形for(intj=0 ; j<m ; j++){int p =0;int q= 0;if(m-1 ==j){a =v[m-1].y- v[0].y;b =v[m-1].x-v[0].y;c=b * v[m-1].y- a * v[m-1].x;}else{a =v[j].y -v[j+1].y;b=v[j].x-v[j+1].x;c = b * v[j].y- a * v[j].x;}for(int k=0; k<m;k++){total[k] = a*v[k].x - b *v[k].y + c;if(total[k] > 0){p= p+1;}elseif(total[k] < 0){q =q+1;}}if((p>0&& q>0) || (p==0 &&q==0)){cout<<"无法构成凸多边形!"<<endl;exit(1);}}}bool minWeightTriangulation()//计算最优值算法{int M;int**t,**s;point*v;for(int i=1 ;i<=M; i++)t[i][i]= 0;for(int r=2;r<=M ; r++)for(int i=1;i<=M-r+1 ;i++){intj=i+r-1;t[i][j] =t[i+1][j] +w(v[i-1],v[i],v[j]);s[i][j] =i;for(int k=i+1; k<i+r-1 ; k++){intu =t[i][k] + t[k+1][j]+w(v[i-1],v[k],v[j]);if(u < t[i][j]){t[i][j]=u;s[i][j]=k;}}}return true;}void Traceback(int i, int j,int **s){if(i== j)return;Traceback(i,s[i][j],s);Traceback(s[i][j]+1,j,s);cout<<"三角形:v"<<i-1<<"v"<<s[i][j]<<"v"<<j<<endl; }int main(){int**s;//记录最优三角剖分中所有三角形信息int **t;//记录最优三角剖分所对应的权函数值point *v; //记录凸多边形各顶点坐标int*total; //记录坐标在直线方程中的值t=new int*[N];s =new int *[N];for(int i=0;i<N; i++){t[i] = newint[N];s[i]=new int[N];}v=new point[N];total= new int[N];if(JudgeInput()){if(minWeightTriangulation()){Traceback(1,M,s);cout<<endl;cout<<"最优权值之和为:"<<t[1][M]<<endl;}}return0;}运行结果:5、流水作业调度#include<iostream>#define N 100usingnamespace std;class Jobtype{/* int operator<=(Jobtypea)const{return(key<=a.key);}*/intkey;intindex;bool job;};voidsort(Jobtype *d,intn){inti,j;Jobtypetemp;bool exchange; //交换标志for(i =0;i <n;i++){ //最多做n-1趟排序exchange= false;//本趟排序开始前,交换标志应为假for(j= n- 1;j>= i;j--)if(d[j+1].key< d[j].key){temp = d[j+1];d[j+1] = d[j];d[j]= temp;exchange=true; //发生了交换,故将交换标志置为真}if(!exchange) //本趟排序未发生交换,提前终止算法return;}}int FlowShop(intn,int*a,int*b,int *c){Jobtype *d =new Jobtype[n];for(int i=0;i<n;i++)//初始化{d[i].key=a[i]>b[i]?b[i]:a[i];//执行时间d[i].job=a[i]<=b[i];// 作业组d[i].index=i;//作业序号}sort(d,n);;int j=0;int k=n-1;for(inti=0;i<n;i++)//最优调度{if(d[i].job){c[j++]=d[i].index;}else{c[k--]=d[i].index;}}j=a[c[0]];k=j+b[c[0]];for(inti=1;i<n;i++){j+=a[c[i]];k=j<k?k+b[c[i]]:j+b[c[i]];}delete d;//回收空间return k;//返回调度时间}int main(){int n,*a,*b,*c;cout<<"作业数:";cin>>n;Jobtype*d = new Jobtype[N];a=new int[N];b=new int[N];c=newint[N];cout<<"请输入作业号和时间:";for(int i=0;i<n;i++){cin>>d[i].index>>d[i].key;}cout << endl;int k=FlowShop(n,a,b,c);cout<<"\n调度时间:"<<k<<endl;cout<<"最优调度序列:";for(int i= 0;i <n; i++) // 输出最优调度序列{cout<<c[i]<<"";}return0;}运行结果:6、0-1背包问题#include <iostream>#include <iomanip>using namespacestd;constint C=10;//容量constint N=5;//个数int max(const inta,const int b){return a>b?a:b;}int min(constint a,const int b){return a<b?a:b;}/*m为记录数组m[i][j]代表在剩有j容量的条件下,从i开始往后的物品中可以取得的最大价值w为重量数组,v为价值数组n为物品个数,c为开始容量则m[1][c]即此背包能剩下的最大价值*/void knapsack(int**m,intn,int c,int*w,in t*v){int jMax = min(w[n]-1,c);//前n-1个物品for(intj=0;j<=jMax;j++)m[n][j]=0;for(int j=w[n];j<=c;j++)m[n][j]=v[n];for(inti=n-1;i>1;i--){jMax=min(w[i]-1,c);for(intj=0;j<=jMax;j++)m[i][j] = m[i+1][j];for(intj=w[i];j<=c;j++)m[i][j] =max(m[i+1][j],m[i+1][j-w[i]]+v[i]);}m[1][c]=m[2][c];if(c>=w[1])m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]);}//找出最优解,0表示不能装,1表示能装void traceback(int **m,int n,int c,int*x,int *w){for(inti=1;i<n;i++){if(m[i][c]==m[i+1][c]) x[i]=0;else{x[i]=1;c-=w[i];}}x[n]=(m[n][c]==0)?0:1;}int main(){int *v=new int[N+1];int*w=new int[N+1];int**m=newint* [N+1];int*x=new int[N+1];for(inti=0;i<N+1;i++){m[i]=new int[C+1];}cout<<"输入重量序列,"<<N<<"个"<<endl;for(inti=1;i<=N;i++)cin>>w[i];cout<<"输入价值序列,"<<N<<"个"<<endl;for(int i=1;i<=N;i++)cin>>v[i];knapsack(m,N,C,w,v);traceback(m,N,C,x,w);cout<<"最优值:"<<m[1][C]<<endl;cout<<"是否装入背包的情况:";for(int i=1;i<=N;i++){cout<<x[i];}for(int i=0;i<N+1;i++){deletem[i];}delete []m;return 0;}运行结果7、最优二叉搜索树#include<iostream>#include<cmath>#include<limits>#define N100using namespace std;const double MAX =numeric_limits<double>::max(); //double的最大值//a[i]为结点i被访问的概率//b[i]为“虚结点”i被访问的概率//m[i][j]用来存放子树(i,j)的期望代价//w[i][j]用来存放子树(i,j)的所有结点(包括虚结点)的a,b概率之和//s[i][j]用来跟踪root的void OptimalBinarySearchTree(double*a,double*b,int n){int s[N][N];doublem[N][N];double w[N][N];int i,j,l,r;for(i=1; i<=n+1; i++){m[i][i-1]=b[i-1];w[i][i-1]=b[i-1];}for(l=1;l<=n;l++){for(i=1; i<=n-l+1;i++){j =l+i-1;m[i][j] = MAX;w[i][j]= w[i][j-1] + a[j] +b[j];for(r=i; r<=j; r++){double k=m[i][r-1] + w[i][j]+m[r+1][j];if(k<m[i][j]){m[i][j] = k;s[i][j]= k;}}}}cout<<m[1][n];}int main(){double a[N],b[N];int n;double sum=0;inti,j,l;cout<<"请输入关键字的个数:"<<endl;cin>>n;cout<<"请输入每个关键字的概率:"<<endl;for(i=1;i<=n; i++){cin>>a[i];sum+= a[i];}cout<<"请输入每个虚拟键的概率:"<<endl;for(i=0; i<=n;i++){cin>>b[i];sum += b[i];}if(abs(sum-1)>0.01){cout<<"输入的概率和不为1,请重新输入"<<endl;}cout<<"最优二叉查找树的期望搜索代价为:";OptimalBinarySearchTree(a,b,n);return 0;}运行结果:实验总结通过实现动态规划的这个题目,对动态规划算法有了进一步的了解。