【算法】游艇租贷

问题

⻓江游艇俱乐部在⻓江上设置了 n 个游艇租聘站,游客可以在这些租聘站租 ⽤游艇,然后在下游的任何⼀个租聘站归还。游艇出租站 i 到 j 的租⾦为 r(i, j),1 ≤i< j≤n,设计⼀个算法,计算从出租站 i 到 j 所需的最少租⾦。

输⼊格式: 第 1 ⾏中有 1 个正整数 n(n<=200),表示有 n 个游艇出租站。 接下来的第 2 到第 n ⾏,第 i ⾏向量包含了第 i-1 站到第 i 站,第 i+1 站, … , 第 n 站的租⾦。

输⼊样例:

在这⾥给出⼀组输⼊。例如:

3 5 15 7

样例说明:表示⼀共有 3 个出租站点,其中:第 1 个站点到第 2 个的租⾦为 5,第 1 个站点到第 3 个的租⾦为 15,第 2 个站点到第 3 个的租⾦为 7

输出格式: 输出从游艇出租站 1 到游艇出租站 n 所需的最少租⾦。

输出样例: 在这⾥给出相应的输出。例如:

12

分析

这道题是一道最短路径的问题,可以使用动态规划算法去实现,我们参考迪杰斯特拉算法的思想,子问题就是起始点0到1、2、3……..n的最短路径,让每个点都作为一次中间点,不断更新起始点到其他点的最短路径,于是就可以得到递推关系式dp[i] = min(dp[i], dp[j]+cost[j][i-j-1]),也就是看看直接到i这个点和先经过j这个点再到i这个点谁的花费比较少,最后dp[n-1]就是我们要求的答案。

下面对代码进行一些解释:

cost[i][j]表示从站点i到站点i+j+1的租用游艇的成本。

dp数组被初始化为每个元素的inf(无穷大),除了第一个元素dp[0]被设置为0。dp数组将用于存储到达每个站点的最小成本。

在内部循环中,代码通过考虑从前一个站点到当前站点的所有可能路径来更新dp[i]的值。它使用公式dp[i] = min(dp[i], dp[j]+cost[j][i-j-1])。这里,dp[j]表示到达站点j的最小成本,而cost[j][i-j-1]表示从站点j到站点i的租用游艇的成本。

循环完成后,从1号站到n号站租用游艇的最小成本将存储在dp[n-1]中。

最后,函数返回dp[n-1]的值。

注意:代码假设cost数组已正确填充了租用游艇的成本。索引i和j用于根据站点编号访问cost数组的正确元素。

代码和运行结果

def min_cost(n, cost):
    # 初始化 dp 数组
    dp = [float("inf") for i in range(n)]
    dp[0] = 0
    # 动态规划,更新 dp 数组
    for i in range(1, n):
        for j in range(i):
            dp[i] = min(dp[i], dp[j]+cost[j][i-j-1])  # 修改此行
    # 返回 dp 数组最后一个元素,即从1号站到n号站租用游艇的最少租金
    return dp[n-1]

# 主程序
n = int(input("请输入游艇租赁站数量:"))
cost = []
for i in range(n-1):
    row = list(map(int, input(f"请输入:").split()))
    cost.append(row)

# 最后一个租赁站到自身的租金为0
cost.append([0])

res = min_cost(n, cost)
print(f"游艇出租站 1 到游艇出租{n}站所需的最少租⾦为: {res}")

这道题的思考关键在于联系最短路径算法,让每个点做一次中间点,不断更新初始点到其他点的最短路径。代码关键点在于递推关系式dp[i] = min(dp[i], dp[j]+cost[j][i-j-1])。其中,dp[i]表示从起始点到达站点i的最小成本,dp[j]表示到达站点j的最小成本,而cost[j][i-j-1]表示从站点j到站点i的租用游艇的成本。代码通过考虑从前一个站点到当前站点的所有可能路径,选择其中最小的成本更新dp[i]的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值