最小路径开销

原文地址 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​​​​​​​

### C语言实现购买苹果最小开销算法 #### 问题描述 假设存在多个供应商,每个供应商有不同的价格表。目标是在满足一定数量需求的情况下,从这些供应商处购买苹果使得总花费最少。 #### 解决方案设计 为了求解这个问题,可以采用贪心算法来获取最优解。具体来说,在所有可用的价格选项中优先选择单价最低的商品直到达到所需的总量为止[^1]。 #### 完整代码示例 下面是一个简单的C语言程序用于模拟上述过程: ```c #include <stdio.h> #include <stdlib.h> // 定义结构体表示每家商店的信息 typedef struct { int price_per_kg; // 单价(元/公斤) int stock; // 库存量(kg) } Shop; int compare(const void *a, const void *b) { return ((Shop *)a)->price_per_kg - ((Shop *)b)->price_per_kg; } double calculateMinimumCost(int nShops, Shop shops[], double requiredKgs) { qsort(shops, nShops, sizeof(Shop), compare); double total_cost = 0.0; for (int i = 0; i < nShops && requiredKgs > 0; ++i) { if (shops[i].stock >= requiredKgs) { // 如果当前店铺有足够的库存,则全部从此店采购 total_cost += requiredKgs * shops[i].price_per_kg; break; } else { // 否则先从此店买光其现有货物再看下一家 total_cost += shops[i].stock * shops[i].price_per_kg; requiredKgs -= shops[i].stock; } } return total_cost; } int main() { // 测试数据初始化 Shop shops[] = {{5, 10}, {7, 20}, {6, 30}}; int nShops = sizeof(shops)/sizeof(shops[0]); printf("The minimum cost to buy %.2f kgs of apples is: %.2f\n", 25.0, calculateMinimumCost(nShops, shops, 25.0)); return 0; } ``` 此段代码实现了如下功能: - 使用`qsort()`函数按照各商铺提供的苹果单价从小到大排序; - 输出最终所需支付的金额作为结果。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值