day1【动态规划】17年阿里内推笔试题(运筹优化算法工程师)

文章描述了一个关于仓库拣货的问题,拣货员沐哲每次拣的货必须比上一个轻,目标是最大化收益。解决方案是采用动态规划算法,定义dp[i][j]表示从位置(i,j)开始能拣到的最多货物数,初始状态为dp[i][j]=1。通过状态转移方程更新dp矩阵,最后找到最大值作为答案。时间复杂度为O(mn^2),其中m和n分别代表行数和列数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

复习运筹优化第一天

1 题目

沐哲是一个菜鸟仓库的一个拣货员,但他有非常个怪异的习惯。每次拣货的重量都要比之前拣的一个轻,每次拣到货后都可以得到1块钱,沐哲想知道这样最多能赚多少钱?
仓库中的货物重量矩阵如下,

32 34 7 33 21 2
13 12 3 11 26 36
16 30 22 1 24 14
20 23 25 5 19 29
27 15 9 17 31 4
6 18 8 10 35 28

沐哲可以从仓库的任何一个货架开始拣货,下一步可以往上走,也可以往下走,当然,向左向右也可以,但必须使得下一个货物重量减小,才会去拣。在上面的仓库中,一条可拣货的路径为 25-22-3。当然30-23-20-16-13-12-3可以拣的货更多。这也是赚钱最多的一条路径。

要求

输入行数、列数和数据矩阵,输出所赚的最大钱数。

例子:

输入:
6 6
32 34 7 33 21 2
13 12 3 11 26 36
16 30 22 1 24 14
20 23 25 5 19 29
27 15 9 17 31 4
6 18 8 10 35 28
输出:
7

2 求解

感觉本题可以使用动态规划算法来解决。

我们定义 dp[i][j]dp[i][j]dp[i][j] 表示从位置 (i,j)(i,j)(i,j) 开始,可以拣到的最多货物数目。其中,iii 表示行坐标,jjj 表示列坐标。

初始状态为 dp[i][j]=1dp[i][j] = 1dp[i][j]=1,因为从任意位置开始,至少可以拣到一个货物。

状态转移方程为:
dp[i][j]dp[i][j]dp[i][j] = max⁡(i,j)∈Ai,j(dp[i][j]+1)\max_{(i,j) \in A_{i,j}}(dp[i][j]+1)max(i,j)Ai,j(dp[i][j]+1)

其中,Ai,jA_{i,j}Ai,j 表示位置 (i,j)(i,j)(i,j) 可以到达的下一个位置集合,也就是满足以下条件的位置 (x,y)(x,y)(x,y) 的集合:

x∈[1,m]x\in[1,m]x[1,m]y∈[1,n]y\in[1,n]y[1,n],即位置 (x,y)(x,y)(x,y) 在仓库范围内。
wx,y<wi,jw_{x,y} < w_{i,j}wx,y<wi,j,即位置 (x,y)(x,y)(x,y) 的货物重量比位置 (i,j)(i,j)(i,j) 的货物重量轻。

最终答案为 dp[i][j]dp[i][j]dp[i][j] 的最大值,即:
max1≤i≤m,1≤j≤ndp[i][j]max_{1≤i≤m,1≤j≤n}dp[i][j]max1im,1jndp[i][j]
其中,wi,jw_{i,j}wi,j 表示位置 (i,j)(i,j)(i,j) 的货物重量。

具体实现时,可以从货架上每个位置开始,按照状态转移方程进行动态规划。由于每个位置都需要计算一次,时间复杂度为 O(mn2)O(mn^2)O(mn2)

3 代码实现

下一篇补上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值