浅谈动态规划优化

2024-09-05 21:32
文章标签 动态 规划 优化 浅谈

本文主要是介绍浅谈动态规划优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

动态规划是解决多阶段决策最优化问题的一种思想方法。

有时动态规划的时间复杂度过高,需要我们对动态规划进行优化。

对动态规划进行优化的普遍方法是重新定义阶段,我们用一个例子来加以说明:


鹰蛋问题:

有一堆共 M 个鹰蛋,一位教授想研究这些鹰蛋的坚硬度 E。他是通过不断从一幢 N 层的楼上向下扔鹰蛋

来确定 E 的,当鹰蛋从第 E 层楼及以下楼层落下 时是不会碎的,但从第(E+1)层楼及以上楼层向下落时会摔碎。

如果鹰蛋未摔碎,还可以继续使用,但如果鹰蛋全碎了却仍未确定 E,这显然是一个失败的实验。教授希望实验是成功的

这里假设所有的鹰蛋都具有相同的坚硬度。给定鹰蛋个数 M 与楼层数 N。 要求最坏情况下确定 E 所需要的最少次数


 

分析这个问题可以知道它是求一个最优值,那么我们很自然想到用动态规划来做题。

可以发现这个问题的阶段还是比较明显的。可以根据鹰蛋数和楼层来划分阶段

定义状态:定义状态dp[i][j]是当i个鹰蛋在长度为j的楼上最坏情况下确定E所需要的最少次数。

                  比如dp[3][5]是指3个鹰蛋在楼层数为5的楼上最坏情况下确定E所需要的最少次数。

 

状态转移:在进行状态转移的时候,我们可以从两方面来考虑,一是考虑该状态可以由什么状态转移过来。如果这方面

                  不容易想的话,可以考虑这个状态可以想什么状态转移。具体到这个问题,我们在楼层数为j的楼上测试i个

                  鹰蛋有j个决策,分别是从第1层扔下,从第2层扔下......从第j层扔下。每次扔下都有两个情况。

                  假设鹰蛋再第k层扔下(1<=k<=j):

                  1. 鹰蛋没碎:如果鹰蛋没碎,那么在楼层数为k-1个楼上测试i个鹰蛋在最坏情况下的最少次数再加上本次测

                      试就是dp[i][j]的值。

                  2. 鹰蛋碎了:如果鹰蛋碎了,那么在楼层数为j-k个楼上测试i-1个鹰蛋在最坏情况下的最少次数再加上本次测

                      试就是dp[i][j]的值。

                  因为题目要求在最坏情况下,所以我们要在两种情况中选一个最大值,又要求最少次数所以要在j个决策中选

                  一个值最小的。

                 所以状态转移方程为dp[i][j] = min{ max{ dp[i-1][j-k], dp[i][k-1] } + 1  | 1<=k<=j };

 

按一个方向求出该问题的解: 根据状态转移方程,可以看出如果我们要得出dp[i][j]的值,我们要得出dp[i-1][]的值和

                dp[i][k-1](k <= j)的值。所以i应该在外循环,从小到大。j应该在内循环,从小到大。

代码如下:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define mmset(a,b) memset(a,b,sizeof(a))
using namespace std;const int INF = 999999999;int dp[55][10005];		//定义状态 /*
2 10 
2 100 
2 300 
25 900
Sample Output
4
14
24
10
*/int main()
{int n,m;while(~scanf("%d%d",&n,&m))	{mmset(dp,0);for(int i = 1; i <= m; i++)		//初始化 dp[1][i] = i;for(int i = 2; i <= n; i++)		//状态转移方程 ,自底而上的求解 {for(int j = 1; j <= m; j++){dp[i][j] = INF;for(int k = 1; k <= j; k++){dp[i][j] = min(max(dp[i-1][k-1],dp[i][j-k]) + 1,dp[i][j]);}}}printf("%d\n",dp[n][m]);}return 0;
}

 

                 

 

这篇关于浅谈动态规划优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140122

相关文章

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

golang实现动态路由的项目实践

《golang实现动态路由的项目实践》本文主要介绍了golang实现动态路由项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习... 目录一、动态路由1.结构体(数据库的定义)2.预加载preload3.添加关联的方法一、动态路由1

SpringBoot中HTTP连接池的配置与优化

《SpringBoot中HTTP连接池的配置与优化》这篇文章主要为大家详细介绍了SpringBoot中HTTP连接池的配置与优化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、HTTP连接池的核心价值二、Spring Boot集成方案方案1:Apache HttpCl

PyTorch高级特性与性能优化方式

《PyTorch高级特性与性能优化方式》:本文主要介绍PyTorch高级特性与性能优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、自动化机制1.自动微分机制2.动态计算图二、性能优化1.内存管理2.GPU加速3.多GPU训练三、分布式训练1.分布式数据

Python Selenium动态渲染页面和抓取的使用指南

《PythonSelenium动态渲染页面和抓取的使用指南》在Web数据采集领域,动态渲染页面已成为现代网站的主流形式,本文将从技术原理,环境配置,核心功能系统讲解Selenium在Python动态... 目录一、Selenium技术架构解析二、环境搭建与基础配置1. 组件安装2. 驱动配置3. 基础操作模

MySQL中like模糊查询的优化方案

《MySQL中like模糊查询的优化方案》在MySQL中,like模糊查询是一种常用的查询方式,但在某些情况下可能会导致性能问题,本文将介绍八种优化MySQL中like模糊查询的方法,需要的朋友可以参... 目录1. 避免以通配符开头的查询2. 使用全文索引(Full-text Index)3. 使用前缀索

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel