递推(一):递推法的基本思想

      所谓递推,是指从已知的初始条件出发,依据某种递推关系,逐次推出所要求的各中间结果及最后结果。其中初始条件或是问题本身已经给定,或是通过对问题的分析与化简后确定。

      利用递推算法求问题规模为n的解的基本思想是:当n=1时,解或为已知,或能非常方便地求得;通过采用递推法构造算法的递推性质,能从已求得的规模为1、2、…、i−1的一系列解,构造出问题规模为i的解。这样,程序可从i=0或i=1出发,重复地由已知至i−1规模的解,通过递推,获得规模为i的解,直至获得规模为n的解。

      可用递推算法求解的问题一般有以下两个特点: (1) 问题可以划分成多个状态; (2) 除初始状态外,其它各个状态都可以用固定的递推关系式来表示。当然,在实际问题中,大多数时候不会直接给出递推关系式,而是需要通过分析各种状态,找出递推关系式。

      利用递推算法解决问题,需要做好以下四个方面的工作:

      (1)确定递推变量

      应用递推算法解决问题,要根据问题的具体实际设置递推变量。递推变量可以是简单变量,也可以是一维或多维数组。从直观角度出发,通常采用一维数组。

      (2)建立递推关系

       递推关系是指如何从变量的前一些值推出其下一个值,或从变量的后一些值推出其上一个值的公式(或关系)。递推关系是递推的依据,是解决递推问题的关键。有些问题,其递推关系是明确的,大多数实际问题并没有现成的明确的递推关系,需根据问题的具体实际,通过分析和推理,才能确定问题的递推关系。

       (3)确定初始(边界)条件

       对所确定的递推变量,要根据问题最简单情形的数据确定递推变量的初始(边界)值,这是递推的基础。

      (4)对递推过程进行控制

      递推过程不能无休止地重复执行下去。递推过程在什么时候结束,满足什么条件结束,这是编写递推算法必须考虑的问题。

       递推过程的控制通常可分为两种情形:一种是所需的递推次数是确定的值,可以计算出来;另一种是所需的递推次数无法确定。对于前一种情况,可以构建一个固定次数的循环来实现对递推过程的控制;对于后一种情况,需要进一步分析出用来结束递推过程的条件。

       递推通常由循环来实现,一般在循环外确定初始(边界)条件,在循环中实施递推。

       递推法从递推方向可分为顺推与倒推。

       所谓顺推法是从已知条件出发,通过递推关系逐步推算出要解决的问题的结果的方法。如求斐波拉契数列的第20项的值,设斐波拉契数列的第n项的为f(n),已知f(1)=1,f(2)=1;通过递推关系式f(n)=f(n-2)+f(n-1) (n>=3,n∈N),可以顺推出f(3)=f(1)+f(2)=2、f(4)=f(2)+f(3)=3、…直至要求的解f(20)=f(18)+f(19)=6765。

      所谓倒推法,就是在不知初始值的情况下,经某种递推关系而获知了问题的解或目标,从这个解或目标出发,采用倒推手段,一步步地倒推到这个问题的初始情况。

      一句话概括:顺推是从条件推出结果,倒推从结果推出条件。

       顺推法是从前往后推,从已求得的规模为1、2、…、i−1的一系列解,推出问题规模为i的解,直至得到规模为n的解。顺推算法可描述为:

for (k=1; k<=i−1; k++)

     f[k]= <初始值>;               // 按初始条件,确定初始值

for (k=i; k<=n; k++)

    f[k]= <递推关系式>;       // 根据递推关系实施递推

cout<<f[n];                   // 输出n规模的解f(n)

       倒推法是从后往前推,从已求得的规模为n、n−1、…、i+1的一系列解,推出问题规模为i的解,直至得到规模为1的解(即初始情况)。倒推算法可描述为:

for (k=n; k>=i+1; k--)

     f[k]= <初始值>;               // 按初始条件,确定初始值

for (k=i; k>=1; k--)

    f[k]= <递推关系式>;       // 根据递推关系实施递推

cout<<f[1];                   // 输出问题的初始情况f(1)

       递推问题一般定义一维数组来保存各项推算结果,较复杂的递推问题还需定义二维数组。例如,当规模为i的解为规模为1、2、…、i−1的解通过计算处理决定时,可利用二重循环处理这一较为复杂的递推。

【例1】RPG涂色问题

      有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三种颜色涂每个格子,每个格子涂一种色,要求任何相邻的方格不能同色,且首尾两格也不同色。

      编写一个程序,输入方格数n(0<n<=30),输出满足要求的全部涂法的种数。

      (1) 编程思路

      设满足要求的n个方格的涂色方法数为F(n)。

      因为RPG有三种颜色,可以先枚举出当方格数为1、2、3时的涂法种数。

      显然,     F(1)=3   (即R、P、G三种)

      F(2)=6   (即RP、RG、PR、PG、GR、GP六种)

      F(3)=6   (即RPG、RGP、PRG、PGR、GRP、GPR六种)

      当方格的个数大于3时,n个方格的涂色方案可以由n-1方格的涂色方案追加最后一个方格的涂色方案得出,分两种情况:

      1)对于已按要求涂好颜色的n-1个方格,在F(n-1)种合法的涂色方案后追加一个方格(第n个方格),由于合法方案的首尾颜色不同(即第n-1个方格的颜色不与第1个方格的相同),这样,第n个方格的颜色也是确定的,它必定是原n-1个方格的首尾两种颜色之外的一种,因此,在这种情况下的涂色方法数为F(n-1)。

      2)对于已按要求涂好颜色的n-2个方格,可以在第n-1个方格中涂与第1个方格相同的颜色,此时由于首尾颜色相同,这是不合法的涂色方案,但可以在第n个方格中涂上一个合法的颜色,使其成为方格长度为n的合法涂色方案(注意:当n等于3时,由于第1(3-2)个方格与第2(3-1)个方格颜色相同,第3个方格不论怎样涂都不会合法,因此递推的前提是n大于3),在第n个方格中可以涂上两种颜色(即首格外的两种颜色,因为与它相连的第n-1个方格和第1个方格的颜色是一样的),因此,在这种情况下的涂色方法数为2*F(n-2)。

由此,可得递推公式:F(n)= F(n-1) + 2*F(n-2)  (n>=4)

程序中定义3个变量f1、f2和f3分别表示F (n-2)、F(n-1)和F(n),初始时f1=6、f2=6。

当n<4时,根据初始情况直接输出结果。

当n>=4时,用循环递推计算F(n)。程序段描述为:

    for(i=4;i<=n;i++)

    {

        f3=f1+f2;          // 计算当前F(i)

        f1=f2;   f2=f3;    // 为下一次递推做准备

    }

      (2)源程序及运行结果

#include <iostream>

using namespace std;

int main()

{

   int i,n,f1,f2,f3,num;

   cout<<"请输入方格的数目 n (0<n<=30):";

   cin>>n;    

   if (n==1)  num=3;

   else if (n==2 || n==3)  num=6;

   else

   {

          f1=6;  f2=6;

       for(i=4;i<=n;i++)  

          {

              f3=2*f1+f2;         // 递推求F(i)

                 f1=f2;  f2=f3;       // 为下次递推做准备

          }

          num=f3;

   }

   cout<<n<<"个方格的正确涂色方案一共有"<<num<<"种。"<<endl;

   return 0;

}

      为更清晰地描述递推过程并保存中间结果,可以定义一个一维数组f[31],数组元素f[i]保存总数为i个方格的涂色方法数。初始值: f[1]=3、f[2]=6、f[3]=6。源程序清单如下。

#include <iostream>

using namespace std;

int main()

{

   int i,n,f[31];

   f[0]=0;   

   f[1]=3;    

   f[2]=6;   

   f[3]=6;    

   for(i=4;i<31;i++)        

          f[i]=f[i-1]+2*f[i-2];    

   cout<<"请输入方格的数目 n (n<=30):";

   cin>>n;    

   cout<<n<<"个方格的正确涂色方案一共有"<<f[n]<<"种。"<<endl;

   return 0;

}

转载于:https://www.cnblogs.com/cs-whut/p/11022438.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248723.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在vue中methods互相调用的方法

在vue中methods互相调用的方法 转载于:https://www.cnblogs.com/macT/p/10212878.html

MUI H5+ 开发app基础

加载子页面(防止手机性能差,出现上下滑动卡顿) 其中 url 就是子页面的路径 id 为自定义 通常和页面名称一致页面的跳转和传值 切记 如果使用mui组件内的底部导航跳转的方式只能使用document获取元素的id 页面跳转传值 新页面接收参数 页面初始化 H5加载完毕 判断某个元素中是…

对象

一、对象 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><script type"text/javascript">/** JS中数据类型* String 字符串* Number 数值* Boolean 布尔值* Null 空值* Undefine…

uni-app 组件传值

uni-app中的组件之间的传值 我们将compontents中的test文件作为子组件 引入到index中使用 引入并使用 效果如下 父传子 首先我们在父组件中使用子组件的标签中去自定义title 在子组件中 通过props去接收并处理 效果如下&#xff1a; 子传父 子组件中 设置一个按钮…

JSP XML数据处理

JSP XML数据处理 当通过HTTP发送XML数据时&#xff0c;就有必要使用JSP来处理传入和流出的XML文档了&#xff0c;比如RSS文档。作为一个XML文档&#xff0c;它仅仅只是一堆文本而已&#xff0c;使用JSP创建XML文档并不比创建一个HTML文档难。 使用JSP发送XML 使用JSP发送XML内容…

Docker 图形界面管理工具 -- Portainer

Portainer&#xff08;基于 Go&#xff09;是一个轻量级的管理界面&#xff0c;可让您轻松管理Docker主机或Swarm集群。 Portainer的使用意图是简单部署。它包含可以在任何 Docker 引擎上运行的单个容器&#xff08;Docker for Linux 和 Docker for Windows&#xff09;。 Port…

vue cli3.0创项目报错‘This may cause things to work incorrectly. Make sure to use the same version for b’

错误&#xff1a; throw new Error(^Error:Vue packages version mismatch:- vue2.6.12 (C:\Users\Administrator\AppData\Roaming\npm\node_modules\vue\dist\vue.runtime.common.js) - vue-template-compiler2.6.11 (C:\Users\Administrator\AppData\Roaming\npm\node_module…

Web程序中使用EasyUI时乱码问题

今天偶然遇见使用easyUI时&#xff0c;弹窗和分页都是乱码的问题&#xff0c;耗费了很长的时间来解决&#xff0c;以此记住这个坑。 相信大家都会在使用easyUI时都会设置这样一句&#xff1a; 那么就有可能出现设置中文后的乱码问题&#xff0c;如下图&#xff1a; 因为在使用e…

关于window对象

window对象 - navigator&#xff08;导航器对象&#xff09; appCodeName&#xff1a;返回浏览器的代码名appName&#xff1a;返回浏览器的名称appVersion&#xff1a;返回浏览器的平台和版本信息cookieEnabled&#xff1a;返回指明浏览器中是否禁用cookie的布尔值platform&a…

160-PHP 文本替换函数str_replace(一)

<?php$strHello world!; //定义源字符串$searcho; //定义将被替换的字符$replaceO; //定义替换的字符串$resstr_replace($search,$replace,$str); //使用函数处理字符串echo "{$str}替换后的效果为&#xff1a;<br />{$res}";…

流的操作规律

IO流中对象很多&#xff0c;解决问题(处理设备上的数据时)到底该用哪个对象呢&#xff1f;   把IO流进行了规律的总结(四个明确)&#xff1a; 明确一&#xff1a;要操作的数据是数据源还是数据目的。 源&#xff1a;InputStream Reader 目的&#xff1a;OutputStream Writ…

看完就懂的编辑页面如何巧妙处理时间

需求分析 分析&#xff1a; 我们通常会遇到这种情况&#xff0c;当我们制作一个表单页面的时候&#xff0c;通常会有添加和编辑的情况&#xff0c;我们在提交的时候还需要将时间的格式转换为字符串格式进行传参。 在这里我们使用的是 iview 中的 DatePicker type格式为datetime…

[转]Tomcat中8005/8009/8080/8443端口的作用

8005&#xff1a;关闭tomcat进程所用。当执行shutdown.sh关闭tomcat时就是连接8005端口执行“SHUTDOWN”命令--由此&#xff0c;我们直接telnet8005端口执行“SHUTDOWN”&#xff08;要大写&#xff0c;小写没用&#xff1b;不运只能telnet 127.0.0.1 8005其他地址telnet都不能…

月入10万和月入5千的人关键区别是什么???

月入10万和月入5千的人关键区别是什么&#xff1f;&#xff1f;&#xff1f;知识体系、决策能力、魄力和格局&#xff01;&#xff01;&#xff01;人不学不知道&#xff0c;看过很多书&#xff0c;学过很多课&#xff0c;发现不久就忘了&#xff0c;很难真正被自己消化吸收&am…

关于“wap2app仅支持对已通过ICP备案的域名站点进行打包”问题解决

关于“wap2app仅支持对已通过ICP备案的域名站点进行打包”问题解决 如果我们是通过Vue技术写的移动端&#xff0c;开发完成后我们的项目需要放到服务器上&#xff0c;然后我们在将服务器上面的项目打包apk格式 wap2app将网页打包成apk步骤 使用HbuilderX创建一下wap2app项目 我…

第五周-第07章节-Python3.5-内置模块详解之OS模块

os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台。比如对于Windows&#xff0c;它是nt&#xff0c;而对于Linux/Unix用户&#xff0c;它是posix。os.getcwd:得到当前工作目录&#xff0c;即当前python脚本工作的目录路径。os.getenv()和os.putenv:分别用…

2021前端面试题总结

HTML CSS 定位 flex布局 display css3新属性 css3的边框-border-radius–box-shadow–border-image 背景 background-size–background-origin &#xff1a;属性规定背景图片的定位区域。文字效果&#xff1a;text-shadow&#xff1a;在 CSS3 中&#xff0c;text-shadow …

mysql之库操作_创建用户_修改用户权限_修改用户密码

用户操作&#xff1a; 1、create user Faye127.0.0.1IDENTIFIED BY 123 #添加一个用户名字为Faye的用户,127.0.0.1为本机的ip,123为密码 补&#xff1a;create user Faye% IDENTIFIED BY 123 #添加一个用户名字为Faye的用户,‘%’的意思为所有人都可以连接Faye这个用户,123为…

前端导出文件,后端返回文件流过大直接干崩溃

前端导出文件 前端很常见的导出需求 导出world xlsx 甚至是zip 在我这个项目中是导出图片&#xff0c;图片量还是蛮大的&#xff0c;直接干崩溃了 我们这里是后端同学直接返回的是文件流 通过调用接口拿到文件流后直接调用下面的方法 export function exportZip(res, name)…

在eclipse中创建第一个java应用程序,并在控制台输出“hello world”。

package com.fs.test;public class HelloWorld {public void aMethod() {}public static void main(String[] args) {System.out.print("Hello world");}}转载于:https://www.cnblogs.com/ooo888ooo/p/11042700.html