算法分析大作业14页_第1页
算法分析大作业14页_第2页
算法分析大作业14页_第3页
算法分析大作业14页_第4页
算法分析大作业14页_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、算法分析大作业动态规划方法解乘法表问题和汽车加油行驶问题目录1.动态规划解乘法表问题1.1问题描述-1.2算法设计思想-1.3设计方法-1.4源代码-1.5最终结果-2.动态规划解汽车加油行驶问题2.1问题描述-2.2算法设计思想-2.3设计方法-2.4源代码-2.5最终结果-3.总结1.动态规划解决乘法表问题1.1问题描述定义于字母表a,b,c)上的乘法表如表所示:依此乘法表,对任一定义于上的字符串,适当加括号表达式后得到一个表达式。例如,对于字符串x=bbbba,它的一个加括号表达式为(b(bb)(ba)。依乘法表,该表达式的值为a。试设计一个动态规划算法,对任一定义于上的字符串x=x1x

2、2xn,计算有多少种不同的加括号方式,使由x导出的加括号表达式的值为a。1.2算法设计思想设常量a,b,c 分别为 1, 2 ,3 。n 为字符串的长度。设字符串的第 i 到 第 j 位乘积为 a 的加括号法有resultija 种,字符串的第 i 到 第 j 位乘积为 b 的加括号法有resultijb 种,字符串的第 i 到 第 j 位乘积为 c 的加括号法有 resultijc 种。则原问题的解是:resultina 。设 k 为 i 到 j 中的某一个字符,则对于 k 从 i 到 j :resultija += resultika * resultk + 1jc + resultikb

3、 * resultk + 1jc + resultikc * resultk + 1ja;resultijb += resultika * resultk + 1ja + resultika * resultk + 1jb + resultikb * resultk + 1jb;resultijc += resultikb * resultk + 1ja + resultikc * resultk + 1jb + resultikc * resultk + 1jc;输入:输入一个以a,b,c组成的任意一个字符串。输出:计算出的加括号方式数。1.3设计方法乘法表问题直观理解就是通过加括号使得最终

4、运算结果为a,该问题与矩阵连乘问题类似,矩阵连乘是每一次加括号选择运算量最小的,写成数学表达式有:而乘法表问题则是计算所有加括号运算结果为a的情况数,并不要求输出加括号方式。那么可以从乘法的最小单元两个符号相乘的所有可能开始,接着在两个符号相乘的基础上计算三个符号相乘的所有可能。直到计算N长度的符号1-N的所有可能。可以定义一个三维数组ann3,n为输入字符串的长度,aij0为从字符串中第i个元素到第j个元素的子串表达式值为a的加括号方式数,aij1为从字符串中第i个元素到第j个元素的子串表达式值为b的加括号方式数,aij2为从字符串中第i个元素到第j个元素的子串表达式值为c的加括号方式数。由

5、乘法表的定义则可知啊aij0=(对k求和,k从i到j-1)aik0*aik+12+aik1*aik+12+aik2*aik+11;同理可得到aij1和aij2。同时由上面的表达式可知,要计算aij,需先计算aik和aik+1,这里k从i到j-1,故aij可采取如下的计算次序1.4源代码#include iostream#include algorithm#include fstreamusing namespace std;/*fij0 表示在chichj之间以某种方式加括号后,结果为afij1 表示在chichj之间以某种方式加括号后,结果为bfij2 表示在chichj之间以某种方式加括号

6、后,结果为ca = a*c | b*c | c*ab = a*a | a*b | b*bc = b*a | c*b | c*c */int f50503;char chars3 = a, b, c;int mul(int n, char ch) for(int i=0; in; i+) for(int k=0; k3; k+) fiik = (chi = charsk ? 1: 0); /* a = a*c | b*c | c*a b = a*a | a*b | b*b c = b*a | c*b | c*c */ for(int r=1; rn; r+) /规模 for(i=0; in-r;

7、 i+) /区间左端点 int j = i + r; /区间右端点 for(int k=i; kj; k+) /断点 fij0 += fik0*fk+1j2 + fik1*fk+1j2 + fik2*fk+1j0; fij1 += fik0*fk+1j0 + fik0*fk+1j1 + fik1*fk+1j1; fij2 += fik1*fk+1j0 + fik2*fk+1j1 + fik2*fk+1j2; return f0n-10;int main() ifstream fin(mul.txt); cout ch; cout ch; int n = strlen(ch); cout n结果

8、为a的加括号方式为: mul(n, ch) endl; fin.close(); return 0;1.5最终结果2.动态规划解决汽车加油行驶问题2.1问题描述给定一个N*N的方形网络,设其左上角为起点,坐标为(1,1),X轴向右为正,Y轴向下为正,每个方格边长为1。一辆汽车从起点出发驶向右下角终点, 其坐标为(M,N)。在若干网格交叉点处,设置了油库,可供汽车在行驶途中,可供汽车在行驶途中加油。汽车在行驶过程中应遵守如下规则:(1)汽车只能沿网格边行驶,装满油后能行驶K条网格边。出发时汽车已装满油,在起点与终点处不设油库。(2)当汽车行驶经过一条网格边时,若其X坐标或Y坐标减小,则应付费用B

9、,否则免付费用。(3)汽车在行驶过程中遇油库则应加满油并付加油费用A。(4)在需要时可在网格点处增设油库,并付增设油库费用C(不含加油费A)。(5)(1)(4)中的各数N,K,A,B,C均为正整数。2.2算法设计思想这个题目,应该说是刚开始的时候被他给吓到了,只是想着如何去把所有的条件构造起来,然后使用网络流的方式来解决问题!但是,如果真的是很冷静下来好好地思考这道题目,就会发现如果没有那些限制条件,就是一个求解最长路的题目,这样就可以直接使用来解决这个问题!关键就是在于这个每次最多只能走个网格边,这样就是限制了活动的范围,使得有的边无法扩展!因此可以考虑使用这个分层思想的最短路问题!就是通过

10、将每一个点进行拆分,这样,就是相当于一种分类讨论的方式!而分类讨论了之后,就知道哪些边是可以扩展的,哪些边是不能扩展的!关键点就是在于该如何选取变量来分层,这就是因情况而异了!像这道题目之中,就是通过油量的多少来扩展边的!分层思想,说穿了其实就是相当于这个动态规划之中的增加变量的方式来确定状态一样,他们的实质其实都是一样的!2.3设计方法采用的是动态规划的思想来解题,用备忘录的方法进行递归,递归的式子后面写出.不能直接以汽车行驶的费用为目标来进行动态规划,因为最优子结构性质得不到证明.所以必须把油量和费用一起考虑,作为动态规划的对象,此时就有了最优子结构性质.最优子结构性质的证明证明:假设路径

11、M是从起点到终点的一条最小费用路径,P(x,y)是M经过的一个点(非加油站),且油量和费用为(g,c),现假设有一条新路径Q从起点到点P(x,y),使得其在P(x,y)点的油量和费用为(g,c),其中c备忘录递归刚开始的时候为每个网格点P(x,y)建立一个记录,初始化时,为该记录存入一个特殊值W,表示汽车未行驶过.那么在汽车行驶过程中,对每个待求的汽车最小费用值COST,先查看其相应的记录项C,如果存储的是初始值W,那么表示这个点P(x,y)是第一次遇到,此时计算出该点的最小费用值,并保存在其相应的记录项中,以备以后查看.若记录项C中存储的不是初始值W,那么表示该问题已经求解过了,其相应的记录

12、项中存储的就是该点的最小费用值COST,此时要取出记录项C的值跟最新的计算出的COST进行比较,取其最小的那个数存入到C中.依此建立记录项C的值,当程序递归完成时,我们也得到了汽车行驶到(n,n)的最小费用值COST.2.4源代码#include iostream#include algorithm#include fstreamusing namespace std;#define INF 10000/*fij0表示汽车从网格点(1,1)行驶至网格点(i,j)所需的最少费用fij1表示汽车行驶至网格点(i,j)还能行驶的网格边数si0表示x轴方向si1表示y轴方向si2表示行驶费用fij0

13、= minf i+sk0 j+sk1 0 + sk2fij1 = f i+sk0 j+sk1 1 - 1;f110 = 0f111 = Kfij0 = fij0 + A , fij1 = K 如果(i, j)是油库fij0 = fij0 + C + A, fij1 = K (i, j)不是油库,且fij1 = 0*/int N; /方形网络规模int A; /汽车在行驶过程中遇到油库应加满油并付加油费Aint C; /在需要时可在网格点处增设油库,并付增设油库费用C(不含加油费A)int B; /当汽车行驶经过一条网格边时,如果其x坐标或y坐标减少,应付费用Bint K; /装满油后,还能行驶

14、K条边int f50502;int s43 = -1,0,0,0,-1,0,1,0,B,0,1,B;int a5050; /方形网络int dyna() int i, j, k; for (i=1;i=N;i+) for (j=1;j=N;j+) fij0=INF; fij1=K; f110 = 0; f111 = K; int count = 1; int tx, ty; while(count) count = 0; for(i=1; i=N; i+) for(int j=1; j=N; j+) if(i=1 & j=1) continue; int minStep = INF; int

15、minDstep; int step, dstep; for(k=0; k4; k+) /可走的四个方向 tx = i + sk0; ty = j + sk1; if(tx1 | tyN | tyN) /如果出界 continue; step = ftxty0 + sk2; dstep = ftxty1 - 1; if(aij = 1) /如果是油库 step += A; dstep = K; if(aij=0 & dstep = 0 & (i!=N|j!=N) /如果不是油库,且油已经用完 step += A + C; dstep = K; if(step minStep) /如果有更优解

16、count+; fij0 = minStep; fij1 = minDstep; return fNN0;int main() ifstream fin(car.txt); cout N; cout N; cout K; cout K; cout A; cout A; cout B; cout B; s22 = s32 = B; cout C; cout C; cout n输入方形网络:n; for(int i=1; i=N; i+) for(int j=1; j aij; cout aij ; cout endl; cout 最优行驶路线所需的费用为: dyna() endl; fin.close(); return 0;2.5最终结果3.总结 动态规划(Dynamic Programming, DP)思想启发于分治

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论