复习运筹优化第一天
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 求解
感觉本题可以使用动态规划算法来解决。
我们定义 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示从位置 ( i , j ) (i,j) (i,j) 开始,可以拣到的最多货物数目。其中, i i i 表示行坐标, j j j 表示列坐标。
初始状态为 d p [ i ] [ j ] = 1 dp[i][j] = 1 dp[i][j]=1,因为从任意位置开始,至少可以拣到一个货物。
状态转移方程为:
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] =
max
(
i
,
j
)
∈
A
i
,
j
(
d
p
[
i
]
[
j
]
+
1
)
\max_{(i,j) \in A_{i,j}}(dp[i][j]+1)
max(i,j)∈Ai,j(dp[i][j]+1)
其中, A i , j A_{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) 在仓库范围内。
w
x
,
y
<
w
i
,
j
w_{x,y} < w_{i,j}
wx,y<wi,j,即位置
(
x
,
y
)
(x,y)
(x,y) 的货物重量比位置
(
i
,
j
)
(i,j)
(i,j) 的货物重量轻。
最终答案为
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 的最大值,即:
m
a
x
1
≤
i
≤
m
,
1
≤
j
≤
n
d
p
[
i
]
[
j
]
max_{1≤i≤m,1≤j≤n}dp[i][j]
max1≤i≤m,1≤j≤ndp[i][j]
其中,
w
i
,
j
w_{i,j}
wi,j 表示位置
(
i
,
j
)
(i,j)
(i,j) 的货物重量。
具体实现时,可以从货架上每个位置开始,按照状态转移方程进行动态规划。由于每个位置都需要计算一次,时间复杂度为 O ( m n 2 ) O(mn^2) O(mn2)。
3 代码实现
下一篇补上