最小路径开销

原文地址 http://www.daileinote.com/computer/math/0f

最小开销路径(Min Cost Path)(MCP),给出一个开销矩阵cost,求得从cost[x][y] 到 cost[i][j] 的最小开销。比如下图

从 (0,0) 到 (2,2) 的最小开销为 8 (1 + 2 + 2 + 3)

想要到达 (m, n),必须经过 (m-1, n-1),(m-1, n),(m, n-1) 其中一个, 所以 minCost(m, n) = min (minCost(m-1, n-1), minCost(m-1, n), minCost(m, n-1)) + cost[m][n]

下面是没有解决重叠子问题的例子

#include <stdio.h>
#include <string.h>
#define dl_max(x,y) ((x) > (y) ? (x) : (y))
#define MAX_COST 1024   // 这里定义一个上限
int dl_min(int x, int y, int z) { if (x < y) return x < z ? x : z; else return y < z ? y : z;}
int min_cost(int cost[3][3], int m, int n)
{
    if (m < 0 || n < 0)
        return MAX_COST;

    if (m == 0 && n == 0)
        return cost[m][n];

    return cost[m][n] + dl_min(min_cost(cost, m-1,n), min_cost(cost, m,n-1), min_cost(cost, m-1,n-1));
}

int main()
{
    int cost[3][3] = {
        {1, 2, 3},
        {4, 8, 2},
        {1, 5, 3}
    };

    printf("min cost: %d\n", min_cost(cost, 2, 2));
}
                                    mC(2, 2)
                          /            |           \
                         /             |            \             
                 mC(1, 1)           mC(1, 2)             mC(2, 1)
              /     |     \       /     |     \           /     |     \ 
             /      |      \     /      |      \         /      |       \
       mC(0,0) mC(0,1) mC(1,0) mC(0,1) mC(0,2) mC(1,1) mC(1,0) mC(1,1) mC(2,0)

上面有很多重复计算的问题,跟其他动态规划问题一样,这里满足 最优子结构 和 重叠子问题,可以构建 arr[][]解决

#include <stdio.h>
#include <string.h>
int dl_min(int x, int y, int z) { if (x < y) return x < z ? x : z; else return y < z ? y : z;}
int min_cost(int cost[3][3], int m, int n)
{
    int     i,j,sum[3][3];

    sum[0][0] = cost[0][0];

    //计算第一列
    for (i = 1; i <= m; i++)
        sum[i][0] = sum[i-1][0] + cost[i][0];
    
    //计算第一行
    for (i = 1; i <=n; i++)
        sum[0][i] = sum[0][i-1] + cost[0][i];

    for (i = 1; i <= m; i++) {
        for (j = 1; j <= n; j++) {
            sum[i][j] = cost[i][j] + dl_min(sum[i-1][j], sum[i][j-1], sum[i-1][j-1]);
        }
    }

    return sum[m][n];
}

int main()
{
    int cost[3][3] = {
        {1, 2, 3},
        {4, 8, 2},
        {1, 5, 3}
    };
    printf("min cost: %d\n", min_cost(cost, 2, 2));
}

时间复杂度为 O(mn)

原文地址 http://www.daileinote.com/computer/math/0f​​​​​​​

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值