Dynamic Programming | Set 6 (Min Cost Path) | GeeksforGeeks
Given a cost matrix cost[][] and a position (m, n) in cost[][], write a function that returns cost of minimum cost path to reach (m, n) from (0, 0).
Optimal Substructure
minCost(m, n) = min (minCost(m-1, n-1), minCost(m-1, n), minCost(m, n-1)) + cost[m][n]
recomputations of same subproblems can be avoided by constructing a temporary array tc[][] in bottom up manner.
http://www.acmerblog.com/jiudu-1529-2403.html
现在有一个8*8的棋盘,上面放着64个价值不等的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于1000),一个人的初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下角,请设计一个算法使其能够获得最大价值的礼物。
http://www.acmerblog.com/jiudu-1532-2406.html
现在有一个8*8的棋盘,上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于100),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下角。从棋盘的左上角移动到右下角的时候的,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,但是拿到的所有的礼物的价值之和不大于一个限定值limit,请设计一个算法请实现,使其能够获得不超过限制值limit的最大价值的礼物。
http://blog.csdn.net/jackie_zhu/article/details/10416395
http://www.acmerblog.com/jiudu-1532-2406.html
Read full article from Dynamic Programming | Set 6 (Min Cost Path) | GeeksforGeeks
Given a cost matrix cost[][] and a position (m, n) in cost[][], write a function that returns cost of minimum cost path to reach (m, n) from (0, 0).
Optimal Substructure
minCost(m, n) = min (minCost(m-1, n-1), minCost(m-1, n), minCost(m, n-1)) + cost[m][n]
recomputations of same subproblems can be avoided by constructing a temporary array tc[][] in bottom up manner.
int
minCost(
int
cost[R][C],
int
m,
int
n)
{
int
i, j;
int
tc[R][C];
tc[0][0] = cost[0][0];
/* Initialize first column of total cost(tc) array */
for
(i = 1; i <= m; i++)
tc[i][0] = tc[i-1][0] + cost[i][0];
/* Initialize first row of tc array */
for
(j = 1; j <= n; j++)
tc[0][j] = tc[0][j-1] + cost[0][j];
/* Construct rest of the tc array */
for
(i = 1; i <= m; i++)
for
(j = 1; j <= n; j++)
tc[i][j] = min(tc[i-1][j-1], tc[i-1][j], tc[i][j-1]) + cost[i][j];
return
tc[m][n];
}
现在有一个8*8的棋盘,上面放着64个价值不等的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于1000),一个人的初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下角,请设计一个算法使其能够获得最大价值的礼物。
03 | int main() { |
04 | while (~ scanf ( "%d" ,&map[0][0])) { |
05 | for (j=1; j<8; j++) { |
06 | scanf ( "%d" ,&map[0][j]); |
07 | map[0][j] += map[0][j-1]; |
08 | } |
09 | for (i=1; i<8; i++) { |
10 | scanf ( "%d" ,&map[i][0]); |
11 | map[i][0] += map[i-1][0]; |
12 | for (j=1; j<8; j++) { |
13 | scanf ( "%d" ,&map[i][j]); |
14 | map[i][j] += (map[i][j-1] > map[i-1][j] ? map[i][j-1]:map[i-1][j]); |
15 | } |
16 | } |
17 | printf ( "%d\n" ,map[7][7]); |
18 | } |
19 | return 0; |
20 | } |
现在有一个8*8的棋盘,上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于100),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下角。从棋盘的左上角移动到右下角的时候的,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,但是拿到的所有的礼物的价值之和不大于一个限定值limit,请设计一个算法请实现,使其能够获得不超过限制值limit的最大价值的礼物。
1. 在棋盘问题的基础上加了一个限制, 礼物数不能超过 limit
2. 这个限制使得状态转移方程需要进行一下变形
3. dp[i][j][k] 表示 第 (i,j) 个格子上限制最大价值为 k 时能够获得的最大价值
dp[i][j][k] = max(dp[i][j-1][k-matrix[i][j]], dp[i-1][j][k-matrix[i][j]]) + matrix[i][j]
4. 初始化时需要设置为 负无穷, 表示没有线路能够在不超过 limit 的情况下得到 (i,j)
int
main( )
{
int
limit;
while
( cin >> limit )
{
for
(
int
i=
0
; i<
8
; i++)
for
(
int
j=
0
; j<
8
; j++)
cin >> a[i][j];
memset(dp,
0
, sizeof(dp));
if
(a[
0
][
0
] <= limit)dp[
0
][
0
][a[
0
][
0
]] =
1
;
for
(
int
i=
0
; i<
9
; i++)
for
(
int
j=
0
; j<
9
; j++)
{
if
(j >
0
)
{
for
(
int
k=limit; k>=a[i][j]; k--)
{
dp[i][j][k] |= dp[i][j-
1
][k-a[i][j]];
}
}
if
(i >
0
)
{
for
(
int
k=limit; k>=a[i][j]; k--)
{
dp[i][j][k] |= dp[i-
1
][j][k-a[i][j]];
}
}
}
int
res = -
1
;
for
(
int
i=limit; i>=
0
; i--)
{
if
(dp[
7
][
7
][i])
{
res = i;
break
;
}
}
cout << res << endl;
}
return
0
;
}
http://www.acmerblog.com/jiudu-1532-2406.html
02 | int map[8][8], i, j, ans, limit; |
03 | void f( int x, int y, int sum) { |
04 | sum += map[x][y]; |
05 | if (sum > limit) |
06 | return ; |
07 | if (x == 7 && y == 7 && sum > ans) |
08 | ans = sum; |
09 | if (x < 7) |
10 | f(x + 1, y, sum); |
11 | if (y < 7) |
12 | f(x, y + 1, sum); |
13 | } |
14 | int main() { |
15 | while (~ scanf ( "%d" ,&limit)) { |
16 | ans = 0; |
17 | for (i=0; i<8; i++) { |
18 | for (j=0; j<8; j++) { |
19 | scanf ( "%d" ,&map[i][j]); |
20 | } |
21 | } |
22 | f(0,0,0); |
23 | if (ans > 0) |
24 | printf ( "%d\n" ,ans); |
25 | else puts ( "-1" ); |
26 | } |
27 | return 0; |
28 | } |