点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

本文转自:机器学习算法实验室

最近遇到一道很经典的有关动态规划的网易面试题:

小Q和牛博士合唱一首歌曲,这首歌曲由n个音调组成,每个音调由一个正整数表示。
对于每个音调要么由小Q演唱要么由牛博士演唱,对于一系列音调演唱的难度等于所有相邻音调变化幅度之和, 例如一个音调序列是8, 8, 13, 12, 那么它的难度等于|8 - 8| + |13 - 8| + |12 - 13| = 6(其中||表示绝对值)。
现在要对把这n个音调分配给小Q或牛博士,让他们演唱的难度之和最小,请你算算最小的难度和是多少。
如样例所示: 小Q选择演唱{5, 6}难度为1, 牛博士选择演唱{1, 2, 1}难度为2,难度之和为3,这一个是最小难度和的方案了。

输入描述:
输入包括两行,第一行一个正整数n(1 ≤ n ≤ 2000) 第二行n个整数v[i](1 ≤ v[i] ≤ 10^6), 表示每个音调。
输出描述:
输出一个整数,表示小Q和牛博士演唱最小的难度和是多少。
输入例子1:
5
1 5 6 2 1
输出例子1:
3

这是一道动态规划的题目。

详细很多同学和我一样,一看到动态规划(Dynamic Programming)和拓扑图等名词就头疼,令人纠结的是很多大公司都会考动态规划的题目,好吧!静下心来去弄懂动态规划的算法原理。

动态规划的思想:

若该问题很复杂,我们考虑将问题分为几个小问题,而且这些小问题相互之间不存在相互调用,这就是动态规划的思想。

如下图有五个阶段,每个阶段有4种选择,求最短路径:

我们用暴力搜索方法去求解,共需要次运算,时间复杂度高达,如果面试利用暴力搜索方法去寻找最优问题,应该达不到所设置的运行时间。

我们用动态规划方法去求解,利用递归思想,先计算S1阶段的最短路径,然后保存该路径,利用递归的思想去求解S2,S3,....,S5,这种方法的时间复杂度。所以说动态规划大大的减小了运行时间。

一说到“递归”,我们想到了什么?没错,那就是递归表达式,动态规划算法称其为状态转移方程,思想是一样的。

若我们知道了状态转移方程,且知道初始状态值,那么我们就可以通过递归去求解算法最优问题,切记动态规划算法能够缩短运行时间的原因在于每次递归后保存了该状态的值。

下面我们用动态规划分析这道面试题:

假设dp[i][j]表示一个人选择第i个音调和另一个人选择第j个音调的最小难度,这里不特指小Q和牛博是的原因是这里的 i 永远大于 j。

i大于j共有两种情况:

1)i =j+1时,我们在完全题目的基础下,写下递归关系(即状态转移方程):

dp[i][j] = dp[i-1][k] + abs(arr[i] - arr[k])    其中 0<=k<i-1

2)i>=j+1时,递归关系:

dp[i][j] = dp[i-1][j] +  abs(arr[i])-arr[i-1])

我们知道了状态转移方程,还需要设置初始值:

由题意可知,难度计算必须要有两个调才能计算。

因此初始值可设置:dp[0][0] = 0,dp[1][0] = 0;

当i = j+1时,dp[i][j]的递推表达式没考虑到一种特殊情况:当一个人是第一次谈第i个调时,之前的 (i-1)个调都是另一个人谈的,就有 dp[i][j] = abs(arr[1]-arr[0]) + abs(arr[2]-arr[1]) + ... + abs(arr[i-1]-arr[i-2])

根据上面的分析编码:

#include<iostream>
#include<vector>
#include<algorithm>using namespace std;int main()
{
int len=0;while(cin >> len)
{
vector<int> arr(len);
for(int i = 0;i < len;i++)
cin>>arr[i];if(len<3)
cout<<"0"<<endl;
else
{
//vector<vector<int>> dp(len,len);
vector<vector<int>> dp(len,vector<int>(len));
vector<int> acc(len);//dp[0][0] = 0 - abs(arr[1] - arr[0]);
dp[0][0] = 0;for(int i = 1;i < len;i++)
{
acc[i] = acc[i-1] + abs(arr[i] - arr[i-1]);
dp[i][i-1] = acc[i-1];
for(int j = 0;j<i-1;j++){
dp[i][j] = dp[i-1][j] + acc[i] - acc[i-1];
dp[i][i-1] = min(dp[i][i-1],dp[i-1][j] + abs(arr[i]-arr[j]));
}
}int min1 = 1e9;
for(int j =0;j<len-1;j++){
min1 = min(min1,dp[len-1][j]);
}
cout<<min1<<endl;
}}
return 0;
}

代码和解题思路参考了网友buaaqlyj的回答:

https://www.nowcoder.com/test/question/done?tid=30725143&qid=126954#summary

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

一道有关动态规划(Dynamic Programming)的网易面试题相关推荐

  1. 动态规划 dynamic programming

    动态规划dynamic programming June,7, 2015 作者:swanGooseMan 出处:http://www.cnblogs.com/swanGooseMan/p/455658 ...

  2. 动态规划(Dynamic Programming)的一些事一些情

    References <算法导论> 最近在回顾算法的知识,特将一些动态规划的重点记录下来,好让以后自己不要忘记. 基本概念 动态规划(Dynamic Programming,简称为DP,下 ...

  3. 运筹学状态转移方程例子_动态规划 Dynamic Programming

    从运筹学和算法的角度综合介绍动态规划 规划论 Mathematical Programming / Mathematical Optimization In mathematics, computer ...

  4. 动态规划|Dynamic Programming

    由于最近课设要用动态规划,翻阅资料学习一下. 动态规划 解决复杂问题的方法,把它们分解成更简单的子问题. 一旦我们看到一些例子,这个定义就有意义了.实际上,我们今天只看解问题的例子 解决DP问题的步骤 ...

  5. 动态规划(Dynamic Programming)与贪心算法(Greedy Algorithm)

    文章目录 动态规划算法(Dynamic Programming) 动态规划问题的属性 应用实例:最长公共子序列问题(Longest Common Subsequence, LCS) 贪心算法(Gree ...

  6. [欠驱动机器人]4,动态规划(Dynamic Programming)

    目录 前言 控制问题变成优化问题 新增成本(Additive cost) 图搜索的最优控制 连续动力学方程 HJB 方程 求出最小控制 数值求解J 方程逼近与数值迭代 线性方程逼近 网格上的值迭代 连 ...

  7. 算法导论-动态规划(dynamic programming)

    动态规划:通过组合子问题的解来解决整个问题. 动态规划的四个步骤: 1)描述最优解的结构: 2)递归定义最优解的值: 3)按自低向上的方式计算最优解的值(首先找到子问题的最优解,解决子问题,最后找到问 ...

  8. 关于简单动态规划(Dynamic Programming)的总结

    Instructions 综上所述(好像没有上)我的DP真的垃圾的一批... 动态规划是用来避免重复计算状态导致效率低的情况,实现动规有记忆化搜索和填表两种方法,但记忆化搜索不能优化空间,所以常用的是 ...

  9. 算法初探-动态规划(Dynamic Programming)

    编程之中接触到很多关于算法的知识,想来整理一番,算是对自己记忆的一个提醒 1.Coin11Problem  问题为:使用最少的三种面值为1,3,5的硬币组合出11元. 重要的是状态以及状态转移方程 d ...

最新文章

  1. webstorm2018修改运行web page端口号,并且让web在本地局域网内用IP访问
  2. ARM汇编之MOV PC,LR
  3. windows中VS卸载opencv配置,重新安装其他版本
  4. java的equals方法_Java LocalDateTime类| 带示例的equals()方法
  5. diag开关什么意思_1P空气开关便宜、好用,为什么电工师傅却要我们买2P空气开关?...
  6. 中缀表达式-后缀表达式M
  7. LXC与宿主机共享目录(七)
  8. 如何在手机上快速制作小一寸证件照
  9. Java开发微信公众号后台
  10. 科学道德与学风-2021雨课堂答案-第4章
  11. 网上购物网站建设方案
  12. 北京小米Java有笔试吗_小米校招笔试题(java)
  13. 从广州出发领略稻城亚丁和一路上的美丽风光
  14. chrome:initiator使用
  15. FlexRay 总线详细介绍
  16. 粉丝突破1600,我感到一丝愧疚
  17. keil5 串口仿真 ASSIGN COM4 S1IN S1OUT
  18. java基础案例教程答案,2021最新版!
  19. Low Resource ASR: The surprising effectiveness of High Resource Transliteration--低资源ASR:高资源音译的惊人效果
  20. 关于爱情的四个寓言故事

热门文章

  1. 掌握深度学习,为什么要用PyTorch、TensorFlow框架?
  2. 作业盒子完成1.5亿美元D轮融资,更名“小盒科技”
  3. 英伟达Q4净利同比降49%,还能继续躺赚吗?
  4. 今晚8点直播 | 详解微软小冰全双工语音对话技术
  5. 算法工程师养成记(附精选面试题)
  6. 对话迈克尔·乔丹:太多人关注个体智能,而不关注体系
  7. HTTP Host 头攻击,这是什么鬼?
  8. 干掉Random:这个类已经成为获取随机数的王者
  9. 图解Spring解决循环依赖
  10. 单元测试框架怎么搭?快来看看新版Junit5的这些神奇之处吧!