暴力递归转动态规划(十五)

题目
给定一个正数n,求n的裂开方法数,
规定:后面的数不能比前面的数小
比如4的裂开方法有:
1+1+1+1、1+1+2、1+3、2+2、0+4 。 5种,所以返回5

暴力递归
用暴力递归方法进行尝试,整体思路是这样:

  1. 暴力递归方法需要参数pre(上一个数拆分的大小是多少)和rest(剩余的数大小是多少)
  2. 因为题目所说,base case也可以进行确定为
    2.1 pre > rest 则return 0 后面的数不能小于前面的数。
    2.2 如果拆分后的rest = 0,代表两种情况:
    第一种是满足pre < rest 的情况下全部拆完, return 1。
    另一种是我pre就是当前要拆分的数本身,此时也算是一种拆分方式,return 1。

代码

public static int ways(int n) {if (n < 0) {return 0;}if (n == 1) {return 1;}return process(1, n);}public static int process(int pre, int rest) {//两个if判断必须这个在前。if (rest == 0) {return 1;}if (pre > rest) {return 0;}int ways = 0;for (int first = pre; first <= rest; first++) {ways += process(first, rest - first);}return ways;}

动态规划
依然是根据暴力递归代码改写动态规划,首先根据可变参数pre、rest 确定dp[][]大小为dp[n + 1][n + 1]。
并且根据base case可以确定dp[0 ~ n][0]位置 = 1。并且dp[pre][pre]位置值也为1。
第一点比较好理解,第二个来解释一下。如下图所示:
在这里插入图片描述
因为我暴力递归中ways主方法pre参数是从1开始尝试,所以pre = 0可以忽略不看。
根据base case rest = 0的列值为1,又因为pre 必须小于 rest ,所以 pre > rest的位置全都默认0,接下来我们来看 √ 位置 pre = 3 rest = 3。
这个位置可以将rest拆分成(1,2)、(2,1)、(3,0)。因为rest 要大于 pre。所以此时只有(3,0)这个选项可以进行拆分。拆分后,pre = 3, rest = 3,所以 √ 位置依赖pre = 3 rest = 0位置的数。
所以可以确定dp[pre][pre]对角线位置的值都为1。

代码

 public static int dp(int n) {if (n < 0) {return 0;}if (n == 1) {return 1;}int[][] dp = new int[n + 1][n + 1];for (int pre = 1; pre <= n; pre++) {dp[pre][0] = 1;dp[pre][pre] = 1;}for (int pre = n - 1; pre >= 1; pre--) {for (int rest = pre + 1; rest <= n; rest++) {int ways = 0;for (int first = pre; first <= rest; first++) {ways += dp[first][rest - first] ;}dp[pre][rest] = ways;}}return dp[1][n];}

再次优化
可以看到动态规划的代码中依然还有枚举过程可以进行优化,我们仍然是画图,看每个dp格子之间的位置依赖。如下图所示:
此时我在(2,4)位置,接下来再次进行拆分,会看到它依赖的格子有(2,2)、(3,1)、(4,0)。
在这里插入图片描述
再看x位置(3,4),继续拆分依赖的是(3,1)、(4,0)位置。

在这里插入图片描述

如果将它抽象化的话,此时的pre rest依赖的就是 pre, rest -pre。和 pre + 1,rest的位置。就可以用这个公式将枚举行为来替换掉。

代码

 public static int bestDP(int n) {if (n < 0) {return 0;}if (n == 1) {return 1;}int[][] dp = new int[n + 1][n + 1];for (int pre = 1; pre <= n; pre++) {dp[pre][0] = 1;dp[pre][pre] = 1;}for (int pre = n - 1; pre >= 1; pre--) {for (int rest = pre + 1; rest <= n; rest++) {dp[pre][rest] = dp[pre + 1][rest] + dp[pre][rest - pre];}}return dp[1][n];}

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

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

相关文章

边缘分布式机器学习

目录 通信机制同步Synchronous异步Asynchronous半同步/延时同步通信的拓扑结构基于迭代式MapReduce的通信&#xff08;同步模式&#xff09;基于MPI之AllReduce的通信&#xff08;同步模式&#xff09;AllReduce有很多变种 基于参数服务器的通信&#xff08;多为异步&#xff0…

傅里叶分析(1)

1 概述 傅里叶分析是信号分析中常用方法之一。傅里叶分析可将信号在时域和频域之间进行转换&#xff0c;从而分析信号在频域上的特点。 傅里叶分析&#xff08;Fourier analysis&#xff09;根据信号的时域数据特征&#xff0c;分为 4 个类别&#xff1a; 傅里叶级数&#x…

如何在 Python 中执行 MySQL 结果限制和分页查询

Python MySQL 限制结果 限制结果数量 示例 1: 获取您自己的 Python 服务器 选择 “customers” 表中的前 5 条记录&#xff1a; import mysql.connectormydb mysql.connector.connect(host"localhost",user"您的用户名",password"您的密码"…

基于安卓android微信小程序的物流仓储系统

项目介绍 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个开发过程首先对物流仓储系统进行需求分析&#xff0c;得出物流仓储系统主要功能。接着对物流仓储系统进行总体设计和详细…

Vue.Draggable 踩坑:add 事件与 change 事件中 newIndex 字段不同之谜

背景 最近在弄自定义表单&#xff0c;需要拖动组件进行表单设计&#xff0c;所以用到了 Vue.Draggable(中文文档)。Vue.Draggable 是一款基于 Sortable.js 实现的 vue 拖拽插件&#xff0c;文档挺简单的&#xff0c;用起来也方便&#xff0c;但没想到接下来给我遇到了灵异事件……

PySide/PYQT如何用Qt Designer和代码来设置文字属性,如何设置文字颜色?

文章目录 📖 介绍 📖🏡 环境 🏡📒 实现方法 📒📝 Qt Designer设置📝 代码📖 介绍 📖 本人介绍如何使用Qt Designer/代码来设置字体属性(包含字体颜色) 🏡 环境 🏡 本文使用Pyside6来进行演示📒 实现方法 📒 📝 Qt Designer设置 首先打开Qt De…

如何在ModelScope社区魔搭下载所需的模型

本篇文章介绍如何在ModelScope社区下载所需的模型。 若您需要在ModelScope平台上有感兴趣的模型并希望能下载至本地&#xff0c;则ModelScope提供了多种下载模型的方式。 使用Library下载模型 若该模型已集成至ModelScope的Library中&#xff0c;则您只需要几行代码即可加载…

PostgreSQL 14.3 源码安装调试

摘要&#xff1a;介绍PostgreSQL 14.3 源码安装&#xff0c;postgresql使用和vscode源码调试。 1. 环境准备 1.1 系统参数修改 systemctl status firewalld.service #查看防火状态 systemctl stop firewalld.service #暂时关闭防火墙 systemctl disable firewalld.service …

爬虫怎么伪装才更安全

随着网络技术的不断发展&#xff0c;爬虫技术也越来越成熟&#xff0c;爬虫伪装技术也随之得到了广泛应用。在爬虫伪装技术中&#xff0c;如何伪装成正常的浏览器行为&#xff0c;让目标网站无法辨别出爬虫的存在&#xff0c;是爬虫伪装技术的核心。下面&#xff0c;我将从以下…

mysql8安装和驱动jar包下载

方式一&#xff1a;基于docker安装 下拉镜像 docker pull mysql:8.0.21 启动镜像 docker run -p 3307:3306 --name mysql -e MYSQL_ROOT_PASSWORDhadoop -d mysql:8.0.21 启动成功后&#xff0c;进入容器内部拷贝配置文件&#xff0c;到宿主主机 docker cp mysql:/etc/mysql…

人工智能基础——图像认知与OpenCV

人工智能的学习之路非常漫长&#xff0c;不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心&#xff0c;我为大家整理了一份600多G的学习资源&#xff0c;基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

pandas笔记:读写excel

1 读excel read_excel函数能够读取的格式包含&#xff1a;xls, xlsx, xlsm, xlsb, odf, ods 和 odt 文件扩展名。 支持读取单一sheet或几个sheet。 1.0 使用的数据 1.1 主要使用方法 pandas.read_excel(io, sheet_name0, header0, namesNone, index_colNone, usecolsNon…

pyqt环境搭建

创建虚拟环境 # 用管理员身份运行 conda create --prefixE:\Python\envs\pyqt5stu python3.6 # 激活虚拟环境 conda activate E:\Python\envs\pyqt5stu # 退出虚拟环境 conda deactivate安装包 pip install PyQt5 -i https://pypi.douban.com/simple pip install PyQt5-tools…

如何用Excel软件制作最小二乘法①

一、用自带的选项&#xff08;不推荐&#xff09;&#xff0c;因为感觉只是近似&#xff0c;虽然结果一样 1.在Excel中输入或打开要进行在excel中输入或打开要进行最小二乘法拟合的数据&#xff0c;如图所示。 2.按住“shift”键的同时&#xff0c;用鼠标左键单击以选择数据&a…

【4】Gradle-快速入门使用【Gradle多模块项目详解】

目录 【4】Gradle-快速入门使用【Gradle多模块项目详解】创建多项目构建添加子项目命名建议 项目依赖项项目路径不同模块的build.gradle配置 子项目之间共享构建逻辑公约插件跨项目配置buildSrc开发公约插件 调整多模块项目配置修改项目树的元素 了解Gralde配置时间和执行时间并…

C#开发的OpenRA游戏之游戏设计思路

OpenRA设计思路 在OpenRA有很多部分的内容,比如UI、渲染、单元行为等等。 不过在地图里,所有单元、建筑物、其它物品都是采用Actor来实现。每个Actor包含一系列Trait属性。 Trait属性有info类和同名称操作类构成。有一个信息类实例在同一类型的所有参与者之间共享。每个Act…

【CSS】全局声明引入自定义字体

以下用vue项目为例&#xff0c;其他的也是类似&#xff01; 在Vue.js中可以使用全局样式表来定义字体。通常&#xff0c;可以在项目中的主样式表中定义全局字体&#xff0c;然后确保该样式表在整个应用程序中被引入。 以下是一般的步骤&#xff1a; 在项目中创建一个全局样式…

CDN是如何减去源机压力的

CDN也叫内容分发网络&#xff08;Content Delivery Network&#xff09;。分布在不同地区的节点服务器组成的分布式网络。通过中心平台的各种功能模块&#xff0c;可以使用户直接访问到就近的节点上&#xff0c;更快获取到需要的内容&#xff0c;大大降低了网络拥堵&#xff0c…

红黑树,AVLTree树(平衡二叉树)迭代器原理讲解

红黑树&#xff0c;AVLTree树底层实现逻辑都是平衡二叉树&#xff08;AVLTree高度平衡&#xff0c;红黑树以某种规则平衡&#xff09;&#xff0c;但终究不像链表的迭代器那样逻辑简单。 简单叙述以下&#xff0c;二叉树上面迭代器的运行逻辑&#xff0c;根据下面的图&#xff…

Nginx:如何实现一个域名访问多个项目

1. 背景介绍 最近在多个项目部署中遇到这样一个问题&#xff0c;一个域名如何实现多个项目的访问。因为不想自己单独去申请域名证书和域名配置&#xff0c;便想到了这个方案&#xff0c;结合Nginx的location功能实现了自己的需求&#xff0c;便记录下来。示例中是以项目演示&a…