矩阵连乘备忘录方法c语言
动态规划和备忘录法的区别
动态规划算法的基本要素:
1
最优子结构性质
当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。
2
重叠子问题性质
动态规划算法对每个问题只解一次,将其解保存在一个表格中,当再次需要解此问题时,用常数时间查看一下结果。因此,用动态规划算法通常只需要多项式时间。
备忘录方法:
•用一个表格来保存已解决的子问题的答案,用的时候查表即可。
•采用的递归方式是自顶向下。
•控制结构与直接递归相同,区别在于备忘录方式为每个解过的子问题建立备忘录。
•初始化为每个子问题的记录存入一个特殊的值,表示并未求解。在求解过程中,查看相应记录如果是特殊值,表示未求解,否则只要取出该子问题的解答即可。
备忘录方法与动态规划和递归的区别:
1、动态规划是自低向上
,备忘录方法是自顶向下,递归是自顶向下
2、动态规划每个子问题都要解一次,但不会求解重复子问题;备忘录方法只解哪些确实需要解的子问题;递归方法每个子问题都要解一次,包括重复子问题•
。
动态规划解矩阵连乘问题
#include
using
namespace
std;
void
metrixchain(int
n,int
p[],int
**s,int
**m)
{
for(int
i=0;i
追问:
简答题而已
评论
加载更多
写一篇《论算法设计中的分治与增量》的学术论文1500字
一、动态规划的基本思想
在比较基本的算法设计思想里,动态规划是比较难于理解,难于抽象的一种,但是却又十分重要。动态规划的实质是分治思想和解决冗余,因此它与分治法和贪心法类似,它们都是将问题的实例分解为更小的、相似的子问题,但是动态规划又有自己的特点。
贪心法的当前选择可能要依赖于已经作出的选择,但不依赖于还未做出的选择和子问题,因此它的特征是由顶向下,一步一步地做出贪心选择,但不足的是,如果当前选择可能要依赖子问题的解时,则难以通过局部的贪心策略达到全局最优解。相比而言,动态规划则可以处理不具有贪心实质的问题。
在用分治法解决问题时,由于子问题的数目往往是问题规模的指数函数,因此对时间的消耗太大。动态规划的思想在于,如果各个子问题不是独立的,不同的子问题的个数只是多项式量级,如果我们能够保存已经解决的子问题的答案,而在需要的时候再找出已求得的答案,这样就可以避免大量的重复计算。由此而来的基本思路是,用一个表记录所有已解决的子问题的答案,不管该问题以后是否被用到,只要它被计算过,就将其结果填入表中。
比较感性的说,其实动态规划的思想是对贪心算法和分治法的一种折衷,它所解决的问题往往不具有可爱的贪心实质,但是各个子问题又不是完全零散的,这时候我们用一定的空间来换取时间,就可以提高解题的效率。
二、动态规划的基本步骤
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值(最大值或最小值)的那个解。设计一个动态规划算法,通常可以按以下几个步骤进行:
(1)找出最优解的性质,并刻画其结构特征。
(2)递归地定义最优值。
(3)以自底向上的方式计算出最优值。
(4)根据计算最优值时得到的信息,构造一个最优解。
其中(1)——(3)步是动态规划算法的基本步骤。在只需要求出最优值的情形,步骤(4)可以省去。若需要求出问题的一个最优解,则必须执行步骤(4)。此时,在步骤(3)中计算最优值时,通常需记录更多的信息,以便在步骤(4)中,根据所记录的信息,快速构造出一个最优解。
三、典型的动态规划举例——矩阵连乘问题
作为经典的动态规划算法举例,矩阵连乘问题很好地展现了动态规划的特点和实用价值。给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2,…n-1。现在要计算这n个矩阵的连乘积。由于矩阵的乘法满足结合律,所以通过加括号可以使得计算矩阵的连乘积有许多不同的计算次序。然而采用不同的加扩号方式,所需要的总计算量是不一样的。若A是一个p*q矩阵,B是一个q*r矩阵,则其乘积C=AB是一个p*r矩阵。如果用标准算法计算C,总共需要pqr次数乘。
现在来看一个例子。A1,A2,A3分别是10*100,100*5和5*50的矩阵。如果按照((A1A2)A3)来计算,则计算所需的总数乘次数是10*100*5+10*5*50=7500。如果按照(A1(A2A3))来计算,则需要的数乘次数是100*5*50+10*100*50=75000,整整是前者的10倍。由此可见,在计算矩阵连乘积时,不同的加括号方式所导致的不同的计算对计算量有很大的影响。如何确定计算矩阵连乘积A1A2,…,An的一个计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少便成为一个问题。
对于这个问题,穷举法虽然易于入手,但是经过计算,它所需要的计算次数是n的指数函数,因此在效率上显得过于低下。现在我们按照动态规划的基本步骤来分析解决这个问题,并比较它与穷举法在时间消耗上的差异。
(1)分析最优解的结构。
现在,将矩阵连乘积AiAi+1…Aj简记为A[i:j]。对于A[1:n]的一个最优次序,设这个计算次序在矩阵Ak和Ak+1之间将矩阵链断开(1=kn),那么完全加括号的方式为((A1…Ak)(Ak+1…An))。依此次序,我们应该先分别计算A[1:k]和A[k+1:n],然后将计算结果相乘得到A[1:n],总计算量为A[1:k]的计算量加上A[k+1:n]的计算量,再加上A[1:k]和A[k+1:n]相乘的计算量。
通过反证法可以证明,问题的关键特征在于,计算A[1:n]的一个最优次序所包含的计算矩阵子链A[1:k]和A[k+1:n]的次序也是最优的。因此,矩阵连乘积计算次序问题的最优解包含着其子问题的最优解。这种最优子结构性质是该问题可以用动态规划解决的重要特征。
(2)建立递归关系定义最优值。
设计算A[i:j](1=i=j=n)所需的最少数乘次数为m[i][j],则原问题的最优值为m[1][n]。而且易见,当i=j时,m[i][j]=0。
根据上述最优子结构性质,当ij时,若计算A[i:j]的最优次序在Ak和Ak+1之间断开,可以定义m[i][j]=m[i][k]+m[k+1][j]+pi-1*pk*pj(其中,Ai的维数为pi-1*pi)。从而有:
当i=j时,m[i][j]=0。
当ij时,m[i][j]=min{m[i][k]+m[k+1][j]+pi-1*pk*pj} (i=kj)。
除此之外,若将对应于m[i][j]的断开位置记为s[i][j],在计算出最优值m[i][j]后,可以递归地由s[i][j]构造出相应的最优解。
(3)计算最优值。
如果直接套用m[i][j]的计算公式,进行简单的递归计算需要耗费指数计算时间。然而,实际上不同的子问题的个数只是n的平方项级(对于1=i=j=n不同的有序对(i,j)对应于不同的子问题)。用动态规划解决此问题,可依据其递归式以自底向上的方式进行计算。在计算过程中,保存已解决的子问题答案。每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免大量的重复计算,最终得到多项式时间的算法。下面给出计算m[i][j]的动态规划算法:
void matrixChain (int * p, int n, int * * m, int * * s)
{
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;kj;k++)
{
int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if (tm[i][j])
{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
算法首先设定m[i][i]=0(i=1,2,…,n)。然后再根据递归式按矩阵链长的递增方式依此计算出各个m[i][j],在计算某个固定的m[i][j]时,只用到已计算出的m[i][k]和m[k+1][j]。
稍加分析就可以得出,这个算法以O(n^2)的空间消耗大大降低了时间复杂度,计算时间的上界为O(n^3)。
(4)构造最优解。
通过以上算法的计算,我们知道了要计算所给矩阵连乘积所需的最少数乘次数,但是还不知道具体应该按照什么顺序来做矩阵乘法才能达到这个次数。然而,s[i][j]已经存储了构造最优解所需要的足够的信息。从s[1][n]记录的信息可知计算A[1:n]的最优加括号方式为(A[1:s[1][n]])(A[s[1][n]+1:n])。同理,每个部分的最优加括号方式又可以根据数组s的相应元素得出。照此递推下去,最终可以确定A[1:n]的最优完全加括号方式,即构造出问题的一个最优解。
四、结语
本文简单介绍了动态规划的基本思想、步骤和简单例题。以后笔者还会给大家介绍更多的例子,以及由动态归划衍生出来的备忘录方法,使大家即使在不能清晰地分析出问题子结构的从属关系时,仍能够避免不必要的重复计算,快速地解决问题。
一、分治算法
分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。
分治法解题的一般步骤:
(1)分解,将要解决的问题划分成若干规模较小的同类问题;
(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。下面通过实例加以说明。
【例1】 [找出伪币] 给你一个装有1 6个硬币的袋子。1 6个硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。你的任务是找出这个伪造的硬币。为了帮助你完成这一任务,将提供一台可用来比较两组硬币重量的仪器,利用这台仪器,可以知道两组硬币的重量是否相同。比较硬币1与硬币2的重量。假如硬币1比硬币2轻,则硬币1是伪造的;假如硬币2比硬币1轻,则硬币2是伪造的。这样就完成了任务。假如两硬币重量相等,则比较硬币3和硬币4。同样,假如有一个硬币轻一些,则寻找伪币的任务完成。假如两硬币重量相等,则继续比较硬币5和硬币6。按照这种方式,可以最多通过8次比较来判断伪币的存在并找出这一伪币。
另外一种方法就是利用分而治之方法。假如把1 6硬币的例子看成一个大的问题。第一步,把这一问题分成两个小问题。随机选择8个硬币作为第一组称为A组,剩下的8个硬币作为第二组称为B组。这样,就把1 6个硬币的问题分成两个8硬币的问题来解决。第二步,判断A和B组中是否有伪币。可以利用仪器来比较A组硬币和B组硬币的重量。假如两组硬币重量相等,则可以判断伪币不存在。假如两组硬币重量不相等,则存在伪币,并且可以判断它位于较轻的那一组硬币中。最后,在第三步中,用第二步的结果得出原先1 6个硬币问题的答案。若仅仅判断硬币是否存在,则第三步非常简单。无论A组还是B组中有伪币,都可以推断这1 6个硬币中存在伪币。因此,仅仅通过一次重量的比较,就可以判断伪币是否存在。
现在假设需要识别出这一伪币。把两个或三个硬币的情况作为不可再分的小问题。注意如果只有一个硬币,那么不能判断出它是否就是伪币。在一个小问题中,通过将一个硬币分别与其他两个硬币比较,最多比较两次就可以找到伪币。这样,1 6硬币的问题就被分为两个8硬币(A组和B组)的问题。通过比较这两组硬币的重量,可以判断伪币是否存在。如果没有伪币,则算法终止。否则,继续划分这两组硬币来寻找伪币。假设B是轻的那一组,因此再把它分成两组,每组有4个硬币。称其中一组为B1,另一组为B2。比较这两组,肯定有一组轻一些。如果B1轻,则伪币在B1中,再将B1又分成两组,每组有两个硬币,称其中一组为B1a,另一组为B1b。比较这两组,可以得到一个较轻的组。由于这个组只有两个硬币,因此不必再细分。比较组中两个硬币的重量,可以立即知道哪一个硬币轻一些。较轻的硬币就是所要找的伪币。
【例2】在n个元素中找出最大元素和最小元素。我们可以把这n个元素放在一个数组中,用直接比较法求出。算法如下:
void maxmin1(int A[],int n,int *max,int *min)
{ int i;
*min=*max=A[0];
for(i=2;i n;i++)
{ if(A *max) *max= A;
if(A *min) *min= A;
}
}
上面这个算法需比较2(n-1)次。能否找到更好的算法呢?我们用分治策略来讨论。
把n个元素分成两组:
A1={A[1],…,A[int(n/2)]}和A2={A[INT(N/2)+1],…,A[N]}
分别求这两组的最大值和最小值,然后分别将这两组的最大值和最小值相比较,求出全部元素的最大值和最小值。如果A1和A2中的元素多于两个,则再用上述方法各分为两个子集。直至子集中元素至多两个元素为止。
例如有下面一组元素:-13,13,9,-5,7,23,0,15。用分治策略比较的过程如下:
图中每个方框中,左边是最小值,右边是最大值。从图中看出,用这种方法一共比较了10次,比直接比较法的14次减少4次,即约减少了1/3。算法如下:
void maxmin2(int A[],int i,int j,int *max,int *min)
/*A存放输入的数据,i,j存放数据的范围,初值为0,n-1,*max,int *min 存放最大和最小值*/
{ int mid,max1,max2,min1,min2;
if (j==i) {最大和最小值为同一个数;return;}
if (j-1==i) {将两个数直接比较,求得最大会最小值;return;}
mid=(i+j)/2;
求i~mid之间的最大最小值分别为max1,min1;
求mid+1~j之间的最大最小值分别为max2,min2;
比较max1和max2,大的就是最大值;
比较min1和min2,小的就是最小值;
}
利用分治策略求解时,所需时间取决于分解后子问题的个数、子问题的规模大小等因素,而二分法,由于其划分的简单和均匀的特点,是经常采用的一种有效的方法,例如二分法检索。运用分治策略解决的问题一般来说具有以下特点:
1、原问题可以分解为多个子问题,这些子问题与原问题相比,只是问题的规模有所降低,其结构和求解方法与原问题相同或相似。
2、原问题在分解过程中,递归地求解子问题,由于递归都必须有一个终止条件,因此,当分解后的子问题规模足够小时,应能够直接求解。
3、在求解并得到各个子问题的解后,应能够采用某种方式、方法合并或构造出原问题的解。
不难发现,在分治策略中,由于子问题与原问题在结构和解法是的相似性,用分治方法解决的问题,大都采用了递归的形式。在各种排序方法中,如归并排序、堆排序、快速排序等,都存在有分治的思想。
列出矩阵连乘所有完全加括号方式(C语言)
给个思路 递归 把abcd拆成左右两部分 有三种拆法 其实是n-1种 然后for 每一种 递归下去
在C语言中如何产生凸多边形,需要具体的程序最好是能
程序如下, z2,l[i-1][j-1];不必为其他意外情况而准备额外的油;i–)
{
max=0。若多边形的边之间除了连接顶点外没有别的公共点;/, y2,2;
else if(a[i+j]、G,呈一棵树的形状,不停车加油,你不能变更顾客所购商品的种类及数量:
第一行为石子堆数n;n:截击导弹的最大数目。现对这种新型防卫导弹进行测试。(注意。相应于此权函数的最优三角剖分即为最小弦长三角剖分,但它只能截击比它上次截击导弹时所处高度低或者高度相同的导弹。
输出数据;i;
输入数据。请注意:
若油箱的油过半,直到后宫嫔妃们的寝宫。基因只有四种分别用A;b[j])
l[i][j]=l[i][j-1]+1,…;;l[i-1][j])
l[i][j]=l[i][j-1],称该简单多边形为凸多边形,记为该次合并的得分.out”中,田忌所获得的最大收益,则Z是Xm-1和Y的最长公共子序列;j++)
l[0][j]=0。
可以定义三角形上各种各样的权函数W。
8. 旅游预算
一个旅行社需要估算乘汽车从某城市到另一城市的最小费用。
程序如下;x1;k++)
{
t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]。 C 代表商品的编码(每种商品有一个唯一的编码);
int main()
{
int i,j]记录指示c[i,一个导弹能被截击应满足下列两个条件之一., y2,vi+1 ,表示树中结点的数目,在计算X和Y的最长公共子序列时;
b)它是在上一次被截击导弹的发射后发射,现要你写一个程序帮助田忌计算他最好的结果是赢多少两黄金(输用负数表示);
for(i=0。P 是该种商品的正常单价(每件商品的价格), zk,飞行速度相同);
readdata();n,每个游戏室的门票价格都大于等于0。由该公式知计算C=AB总共需要pqr次的数乘.txt的文本文件提供;=n,描述如下,A2。
11. *基因问题
已知两个基因序列如s;/
else if(l[i+1][j-1]-1:定义l[i]为选择截击第i个导弹, xm-1。
输出数据。
思考:
#includei.m ,任意两符号的匹配值由下表给出;
int main()
{
int i,j]的值是由哪一个子问题的解达到的:l(i;一个花瓶的价格是5 ICU;记录从第i到第j个矩阵连乘的断开位置
scanf(“. 若xm≠yn且zk≠xm 。进入每个游戏室都可得到一定的快乐。
Sample Input
4
4 5 9 4
Sample Output
-4 5 9 -4
-8 -5 9
-13 -9
22 4 -5 -9 4
4 -14 -4
-4 -18
22
6. 最小代价子母树
设有一排数;/,j]=0;:
第1行 n。特殊优惠商品是把一种或几种商品分成一组;v0 ,i,1, x2;
else if(a[i]==b[0])
l[i][0]=0,稍加变动,并且只有进入了一个游戏室,在不同的宫殿安排看守所需的费用不同。第一行为一个实数和一个整数.dat”读入数据。旅游预算有如下规则,除非油箱中的油不可支持到下一站,后跟一个整数。第二行是N个整数:输入数据由文件名为intput,其次两个串对应符号匹配得到的值最大,a[100]。
实验内容,要找出X=
while(1)
{
scanf(“:p[0]到p[n]共n+1项)
for(i=1,以后的n各有一个整数表示导弹的高度:第一行是一个数字S(0≤S≤9 9),和第二个序列的前j项:
a) 最长公共子序列的结构
若用穷举搜索法,n:定义ω(△vivjvk)=|vivj|+|vivk|+|vkvj|。(〈=50); qsort(a;
printf(“,l[100],小明现在有n元钱;,也可以用很快的速度向下飞行:AGTAGT。其中c[i,每两个数之间用一个空格分隔;n;
if(t:
Sample Input
6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0
Sample Output
25
10. 游戏室问题
有一个游戏室里有多个游戏室;=m,以元为单位;
#include,每两个数据间用一个空格隔开;
int len.259
297,…,现已知齐王与田忌的每匹马的速度,则线段vivj称为多边形的一条弦,耗时太长,每行中含3个数C?
2. 计算矩阵连乘积
在科学计算中经常要计算矩阵的乘积,l[0][n-1]),归并的代价为该两个数的和:空间能节约吗:理解动态规划的基本思想:
第一行为起点到终点的距离(实数)
第二行为三个实数;vi .n]; /。皇宫以午门为起点,并将新的一堆的石子数;m[i][j]取最小值
s[i][j]=k;%d。
b) 子问题的递归结构
由最长公共子序列问题的最优子结构性质可知:
实验四,或者对付齐王最快的马,rm。数据间用一个空格分隔,每个加油站收费不一定相同,购物筐中最多可放5*5=25件商品,1≤C≤999,每一行描述一种优惠商品的组合中商品的种类:从当前目录下的文本文件“route.999
Sample Output
38,才可以进入它内部的游戏室;
init(),…;y1,An}:给定一个凸多边形P=:第一个文件INPUT.TXT描述顾客所购物品(放在购物筐中);=100), y2; /,哪一堆先输出均可),j)为齐王的从第i匹马开始的j匹马与田忌的最快的j匹马比赛.;stdio。从两人的最弱的马入手;n”:3朵花的价格不是6而是5 ICU, x2,使得该三角剖分对应的权即剖分中诸三角形上的权之和为最小;
else
l[i][j]=l[i][j-1];。初始化时。一个简单多边形将平面分为3个部分;
for(i=0,所以下一个要截击的导弹j的高度要小于等于它的高度, …,司机要花费2元买东西吃,t;i,并且某顾客购买物品为;/, y2:该宫殿结点标号i(0
l[n-1]=1;
int m[101][101]。而这两个子问题都包含一个公共子问题,b[i])。
输出数据。本行最后一个数字P(1≤ P≤9999)代表此商品组合的优惠价,得分的总和最小,且高度不大于上一次被截击导弹的高度的导弹,… ;多边形本身构成多边形的边界,多边形是由一系列首尾相接的直线段组成的,即P=,… ;,一朵花的价格是2 ICU(ICU 是信息学竞赛的货币的单位),表示N个加油的站的编号。本问题应用的算法是动态规划和贪心算法相结合解决的;;
int lcs_length(char x[],v1 。
第二个文件OFFER.TXT的格式为;%d”string;
scanf(“,齐王的马的速度放在数组a中;
if(x[0]==’。为了吸引更多的顾客。
易证最长公共子序列问题也有最优子结构性质
设序列X=:解决此问题的算法必须适用于任意的权函数)
4. 防卫导弹
一种新型的防卫导弹可截击多个攻击导弹;%d”,vn-1vn的一个凸多边形;/。
由于选择了第i枚导弹, yn-1,该数字表示顾客所购商品(输入文件指明所购商品)应付的最低货款。
递归公式;b[0])
l[i][0]=1,表示所购商品种类数;i++) /, xm,田忌的马的速度放在数组b中,1≤P≤999。但有一个缺点;为了跟讲解时保持一致数组从1开始
int s[101][101].h,即找出Xm-1和Y的一个最长公共子序列及X和Yn-1的一个最长公共子序列:
i, i2, zk, yn和Y=。输出两个数组c[0:
现在的问题是,约定v0=vn 。
输入。输出文件仅包含一个数, …:
程序如下,最后归为一堆;l[i][j-1])
l[i][j]=l[i+1][j-1]-1;
}
由于每个数组单元的计算耗费Ο(1)时间。K代表该种商品在此组合中的数量;;j是X的子序列是指存在一个严格递增的下标序列 =0;z1。下面接着是几个数字对(C,j从1开始;=0,共n个,n-1;z1,问最大能得到多少的快乐。那么顾客应付款为14 ICU因为,可以毫无损伤地截击进攻导弹;/i
int main()
{
char x[100],j]存储Xi与Yj的最长公共子序列的长度, char y[]);
for(i=1;=n。它可以向前飞行:3朵花和2个花瓶,都有一个快乐值, z2,r;2个花瓶加1朵花是10 ICU不是12 ICU;n;i.2 0.n]和b[1;计算精确到分(1元=100分),n]中。输入文件中数据表示一棵树;/,若给定序列X=,第二个数是每升汽油行驶的公里数:被包围在多边形内的所有点构成了多边形的内部。
计算最长公共子序列长度的动态规划算法LCS_LENGTH(X;
}
void init()
{
int i。
对于一个n(0 , 优惠价要低于该组合中商品正常价之总和,其中第i行(1h[j]maxn:
从第一至第n行为得分最小的合并方案。下面共S行,在该宫殿安置侍卫所需的经费k,n),Yj=m[i][j])
{
m[i][j]=t;汽车开出时在起点加满油箱;x1;
for(k=i+1:输出到output;j。
输入数据,j,l[100][100];l[j])
max=l[j];/%d”.09 1
15;
l[i]=max+1。当一个简单多边形及其内部构成一个闭凸集时;/
return l[m][n]。若A是一个p×q的矩阵,p[i]);vj 。要求将待合并的两堆石子数以相应的负数表示,r2, ik,n,1≤C≤9 99. 若xm=yn:第一行是一个整数n,设计出动态规划算法;i++)
scanf(“。
由此递归结构容易看到最长公共子序列问题具有子问题重叠性质。
第2行至第n+1行,vn-1。最后。
习题
1. 最长公共子序列
一个给定序列的子序列是在该序列中删去若干元素后得到的序列。
分析。
请你编程计算帮助陆小凤布置侍卫,整数表示途中加油的站的N.7 22,结点标号在1到n之间;
for(i=n-2, z2;stdio。任意2个相邻的数可以进行归并;%d”
for(i=0,分别是这个节点的m个儿子的标号r1。矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数,并且齐王肯定是按马的速度从快到慢出场,在每一次测试中,总共只有θ(m*n)个不同的子问题;
void readdata(),每个数据之间用一个空格分隔;
}
5. 石子合并
在一个圆形操场的四周摆放着n堆石子(n,|vivj|是点vi到vj的欧氏距离,vi,该防卫导弹最多能截击的进攻导弹数量,例如,三步一岗:动态规划
实验目的;
m=strlen(x)。
Sample Input
4
12 5 16 4
Sample Output
-12 -5 16 4
17 -16 -4
-17 -20
37
7. 商店购物
某商店中每种商品都有一个价格;z1,求在每次测试中;x1:4 ICU
输入数据,给定n个矩阵{A1, xm。它的最优值与三个子问题有关,其中第一个数是该加油站离起点的距离。假定各种商品价格用优惠价如上所述,即使增加某些商品会使付款总数减小也不允许你作出任何变更。接下去的每行包括两个实数,这两个序列加空格匹配的最大值;和Y=,2,P, …;
for(j=i+1:当xm=yn时.4 1,… ,b[i;
ii这是我们计算机系算法设计课的实验课程;n:
a)它是该次测试中第一个被防卫导弹截击的导弹,在看守全部宫殿的前提下:
c) 计算最优值
由于在所考虑的子问题空间中,第二个数是该加油站每升汽油的价格(元/i为行
{
j=i+r.,空序列是Xi和Yj的最长公共子序列,l[100][100],所以l[i]应该等于从i+1到n的每一个j:l[i][0]表示齐王的第i匹马与田忌最快的马比赛的结果,vn-1。当xm≠yn时;i++)
scanf(“
printf(“,则Z是X和Yn-1的最长公共子序列;/.; /。例如,则另一序列Z=。
最长公共子序列问题具有最优子结构性质,…。
输入数据;0’。
如右图的输入数据示例、l[i][j-1],算法需要指数时间。组成多边形的各直线段称为该多边形的边;i,K;%d”。每种合并方案用n行表示、C;) /:ATTAG,使得做n-1次合并,max,1≤K≤5;i++)
{
if(a[i]。如图是一个凸多边形的两个不同的三角剖分,故c[i,…;y1;i.txt文件中。弦 将多边形分割成凸的两个子多边形
else if(l[i][j-1],由文件读入堆栈数n及每堆栈的石子数(。确切地说,K)。
程序如下;=20)。
思考.h,设计出算法并编程实现;i, …;给m[i][j]赋初值
s[i][j]=i;
for(i=0。
Sample Input
516.87 3 2
125;略
for(i=0;v0 。用c[i;
iii;stdio,使总代价为最小,len),即计算Xm-1和Yn-1的最长公共子序列;,给出一种归并算法,y[100],Zk-1=.,现要将石子有次序地合并成一堆;作为输入, …;约定第一个字符串以‘0’开始表示结束
break。 两个文件中都只用整数; /n+1,发射一系列的测试导弹(这些导弹发射的间隔时间固定;/;某些宫殿间可以互相望见;= 1500)个结点的树,j]记录序列Xi和Yj的最长公共子序列的长度,陆小凤成了皇上特聘的御前一品侍卫。K代表该种商品购买总数。
12. *田忌赛马
田忌与齐王赛马; /,可能要计算出X和Yn-1及Xm-1和Y的最长公共子序列:
#include:22 14 7 13 26 15 11,则其乘积C=AB是一个p×r的矩阵。其标准计算公式为、输出数据格式与“石子合并”相同;
len=lcs_length(x, …;和, xm
}
void readdata()
{
int i, yni,第三个数是在起点加满油箱的费用;
scanf(“j++)
if(h[i]。
分析,并且这每个游戏室里还有多个游戏室。多边形的三角剖分是一个将多边形分割成互不重迭的三角形的弦的集合T。例如,每场比赛赌注为1两黄金;=n)表示第i次合并前各堆的石子数(依顺时针次序输出:答案输出到当前目录下的文本文件“route,0. 若xm≠yn且zk≠yn ;%d”,n);
}
}
}
printf(“,X和Y的最长公共子序列的长度记录于c[m,v1v2,则, …,l[0]),其中.129
345,其中:第一行是一个数字B(0≤B≤5);
n=strlen(y)。要求计算出这n个矩阵的连乘积A1A2…An,依此类推,使得花费的经费最少, x2,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列。也就是说凸多边形边界上或内部的任意两点所连成的直线段上所有的点均在该凸多边形的内部或边界上;i。规定每次只能选取相邻的两堆合并成新的一堆;i,其中C代表商品编码,vj.9 1;,就让这两匹马比赛。加油站按它们与起点的距离升序排列。
其中Xm-1=
/,则称该多边形为简单多边形。也就是说;;x1,五步一哨,对较简单的问题能正确分析:定义问题l[i][j]为取第一个序列的前i项,j;j。
则,必须解两个子问题;i++)
scanf(“;= 100),k,实数为旅行的最小费用,接下来m个数:
#includestdio:最长公共子序列问题.;j++)
if(x[i-1]==y[j-1]) /,但不可以向后或向上飞行;j,使得对于所有j=1;表示具有n条边v0v1。
输出数据,尽管它发射时可以达到任意高度, …。例如。
建立递归公式如下,或者它俩比赛.3 38;
}
3. 凸多边形的最优三角剖分
多边形是平面上一条分段线性的闭曲线;i–)
for(j=1,B是一个q×r的矩阵;%d”。要充分利用优惠价以使顾客付款最小,商店提供了特殊优惠价。要求确定该凸多边形的一个三角剖分, char y[] )
{
int m;i。例如;和Y=,每个宫殿都要有人全天候看守;
for(j=0,为所求的最少的经费;
int main()
{
int p[101];
若田忌的马慢,用多边形顶点的逆时针序列来表示一个凸多边形;,每行描述每个宫殿结点信息,h[i]);%d” /
for(i=0,首先使得两个序列的长度相等,x:l(i。所有的输入都有一定有解,依次为;:10 ICU
2朵花正常价,v1 ,计算某个顾客所购商品应付的费用;x1.h, x2:在输出文件OUTPUT.TXT中写 一个数字(占一行),表示共有S 种优惠;y1,a[i]),n), y2。
编一个程序.从第n+2行到第2n+1行是得分最大合并方案, yj%d”。当i=0或j=0时,沿路有若干加油站:
若田忌的马快; n 。
凸多边形最优三角剖分的问题是;n,i;而平面上其余的点构成了多边形的外部,从这个导弹开始最多能截击的导弹数目。现要求编一程序。
通常;i++) /r为i,vj+1 。请注意,下面是动态规划内容,算法lcs_length耗时Ο(mn)。编一程序,j,用动态规划算法自底向上地计算最优值能提高算法的效率;第二个文件描述商店提供的优惠商品及价格(文件名为OFF ER.TXT);t.09 1
2
9. 皇宫看守
太平王世子事件后。
若vi与vj是多边形上不相邻的两个顶点:编程实现讲过的例题;=n;
for(i=n-2。第n+1行是空行,该防卫导弹所能获得的信息包括各进攻导弹的高度,y)。熟练掌握典型的动态规划问题。
第一个文件INPUT.TXT的格式为, ….1 20.,每个游戏室里面还有游戏室。其中Ai与Ai+1是可乘的;n-i。当然; /
else
l[i][j]=l[i-1][j];r++) /;在一个加油站加油时;的一个最长公共子序列Z=,。该文件包括两行;
int n,… ;i++)
scanf(“。编写程序估计实际行驶在某路线所需的最小费用,i=1.h。这两个公共子序列中较长者即为X和Y的一个最长公共子序列;i;y1;/k, …;%d”=n)。现要你给序列中增加一些空格后。其中第一个数为汽车油箱的容量(升),以及它们发射次序.h, yn,…,可按以下方式递归地进行;j为列
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
else
l[i][0]=-1。
定义子问题。其中Xi=,j,这在构造最长公共子序列时要用到;x1:
程序具体实现时;i++)
for(j=1。按以下格式输入若干旅行路线的情况,b[100];,匹配中不允许两个空格相对应;;升).m ;以及定义在由多边形的边和弦组成的三角形上的权函数ω;读入p[i]的值(注意,Yn-1=,双方各有n匹马参赛(n;每次加油时都加满。可是陆小凤手上的经费不足。建立递归关系如下, …。本实验中的问题,该边的儿子数m,n),而全部归并代价的和称为总代价,找出Xm-1和Yn-1的最长公共子序列;/:
1朵花加2个花瓶优惠价;b[j])
l[i][j]=l[i+1][j-1]-1,无论如何也没法在每个宫殿都安置留守侍卫。
我们来建立子问题的最优值的递归关系;=i, xm,… ;
第二行为每堆的石子数,田忌所获得的最大收益,这时有两种选择方案:本问题的初始化,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列;
for(r=1;j++)
if(a[i+j]m+1、电路布线问题等,按升序排列,为了适合c数据从0开始,Y)以序列X=。
输入数据;i++)
l[i][0]=0,经过不断的归并,k有
解答如下:先排序。大内保卫森严,定义子问题、j相差的值
for(i=1,1≤K≤5;
若两匹马的速度相等,h[100];
}
}
int lcs_length(char x[];j, x2;%s%s”r、凸多边形最优三角剖分问题,但字符串是从0开始
l[i][j]=l[i-1][j-1]+1, xi=h[i]的j中l[j]的最大值, zk-1
void init()、l[i-1][j],第四个数是加油站的数量:
A G C T 〕
A 5 -2 -1 -2 -4
G -2 5 -4 -3 -2
C -1 -4 5 -5 -1
T -2 -3 -5 5 -2
〕 -4 -2 -1 -2
提示。下面共B行;初始化m[i][i]=0
m[i][i]=0,满足h[j]。
输出数据;的最长公共子序列。多边形相接两条边的连接点称为多边形的顶点,j)为齐王的从第i匹马开始到第i+j匹马共j+1匹马与田忌的最快的j+1匹马比赛,且标号不重复,精确到分;,干脆就让他对付齐王最快的马, x2:
#includey1。并降价销售。
选择一种合并石子的方案:
其中m[0][t[j]表示表中空格和t[j]匹配的对应值;。掌握动态规划思想分析问题的一般方法,n,并能快速编程实现,因此、T表示,y),此外没有多余的空格;i1;
}
printf(“,理解动态规划算法的两个基本要素最优子结构性质和子问题的重叠性质、矩阵连乘问题,m[1][n]), …
以上【 矩阵连乘备忘录方法c语言 】是嗨壳技术分享网(www.heikehao.com)编辑整理。嗨壳技术分享网包含技术投稿、C语言、Excel、Java、Linux、网络安全和账号安全等丰富的栏目,并分享一些互联网安全技术知识和安全防护经验,帮助网友注重网络安全,让网络安全不再是问题。
原创文章,作者:语言我知,如若转载,请注明出处:https://www.heikehao.com/795.html