买火车票dp

本文介绍了一个关于铁路旅行的动态规划问题,如何从一个车站到另一个车站购买最少成本的火车票。问题涉及不同票价区间以及直达票限制。通过递推公式 dp[b]=min(dp[a]+got(b-a),dp[b]) 来求解最小花费。" 104305894,7242646,Spring Boot 2.1后如何显示启动日志中的请求路径,"['Spring Boot', 'Web开发', '日志管理', '配置', 'DEBUG', 'INFO']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

Description

Format

Input

Output

Samples

输入数据 1

输出数据 1

 分析

代码


Description

现在有一条“叶卡特琳堡-斯维尔德洛夫斯克”铁路线。它有若干个火车站。这个铁路线可以用一条线段来表示, 而火车站就是线段上的点。铁路起始于叶卡特琳堡(Eakterinburg),终止于斯维尔德洛夫斯克(Sverlovsk),且各 站从叶卡特琳堡(它的编号是1)至斯维尔德洛夫斯克(终点)编号。

两个站之间的票价跟两站的距离有如下关系

两站间的距离x       票价

    0<x<=L1              c1

    L1<x<=L2            c2

    L2<x<=L3            c3

当且仅当两站间距离不大于L3时才能购买这两站之间的直达车票。

所以有时须要购买若干张票来完成整个旅行。 例如,在上图,整条铁路有七个站。从第2站不能直达第6站(因为距离大于L3),但有另外几种方法购票。其中一种 是买两张票:一张是从第2站至第3站(票价为C2),另一张是从第3站至第6站(票价为C3),注意,虽然从第2站至第6 站的距离为2×L2,但不可以买两张价值C2的票,因为一张票只可以用一次且起点和终点必须在车站上。 你的任务时计算给出的两站之间的最小花费。

Format

Input

第一行包含六个由空格隔开的整数L1,L2,L3,C1,C2,C3(1<=L1第二行为车站数N(2<=N<=10000)。 第三行有两个由空格隔开的不等的整数,表示旅行起点和终点(不保证终点大于起点) 接下来的N-1行为起点(叶卡特琳堡)至其它站的距离。这些距离为互不相等的正整数而且呈上升序列。 从叶卡特琳堡至斯维尔德洛夫斯克的距离不超过10^9。 任意两相邻站之间的距离不超过L3。旅行最小花费不超过10^9。

Output

一个整数------最小花费。

Samples

输入数据 1

3 6 8 20 30 40
7
2 6
3
7
8
13
15
23​

输出数据 1

70

 分析

吐槽一句,这题面可真够啰嗦的。

对于这道题,我们可以很容易得出:递推公式如果可以从a站点坐到b站点,那么就很容易可以得出

dp[b]=min(dp[a]+got(b-a),dp[b]);

(got代表由距离求价格)

然后这道题就做完了我自己都不信

细节:注意题目中加标记的字了吗?

代码

#include<bits/stdc++.h>
using namespace std;
int l1,l2,l3,p1,p2,p3;
int n,in,a,r[11000];
int beg,en;
long long dp[11000];
long long got(int y)
{
	if(y==0)
		return 0;
	if(0<y&&y<=l1)
		return p1;
	else
		if(l1<y&&y<=l2)
			return p2;
		else
			if(l2<y&&y<=l3)
				return p3;
			else
				return LONG_LONG_MAX;
}
int main()
{
	memset(dp,0x3f,sizeof(dp));
	cin>>l1>>l2>>l3>>p1>>p2>>p3;
	cin>>n;
	cin>>beg>>en;
	for(int i=2;i<=n;i++)
	{
		cin>>in;
		r[i]=in;
	}
	if(beg>en)
		swap(beg,en);
	dp[beg]=0;
	for(int i=beg;i<=en;i++)
		for(int j=i-1;j>=beg;j--)
			if(LONG_LONG_MAX-got(r[i]-r[j]))
				dp[i]=min(dp[i],dp[j]+got(r[i]-r[j]));
	cout<<dp[en];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值