最小花费

时间限制:1秒  空间限制:65536K  热度指数:683
 算法知识视频讲解

题目描述

在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对应关系如下: 距离s           票价 0<S<=L1         C1 L1<S<=L2        C2 L2<S<=L3        C3 输入保证0<L1<L2<L3<10^9,0<C1<C2<C3<10^9。 每两个站之间的距离不超过L3。 当乘客要移动的两个站的距离大于L3的时候,可以选择从中间一个站下车,然后买票再上车,所以乘客整个过程中至少会买两张票。 现在给你一个 L1,L2,L3,C1,C2,C3。然后是A B的值,其分别为乘客旅程的起始站和终点站。 然后输入N,N为该线路上的总的火车站数目,然后输入N-1个整数,分别代表从该线路上的第一个站,到第2个站,第3个站,……,第N个站的距离。 根据输入,输出乘客从A到B站的最小花费。

输入描述:

以如下格式输入数据:
L1  L2  L3  C1  C2  C3
A  B
N
a[2]
a[3]
……
a[N]

输出描述:

可能有多组测试数据,对于每一组数据,
根据输入,输出乘客从A到B站的最小花费。
示例1

输入

1 2 3 1 2 3
1 2
2
2

输出

2

动态规划问题

// pat.cpp : 定义控制台应用程序的

//#include "stdafx.h"
#include"stdio.h"
#include<iostream>
using namespace std;
//typedef long long ll;
int l1,l2,l3,c1,c2,c3,a,b,n;

int *d;
int l;
int cal(int l){

	if(l<=l1)return c1;
	else if(l<=l2)return c2;
	else if(l<=l3)return c3;
	else return c3*n;

}

int main(){

	//freopen("c://jin.txt","r",stdin);
	while(cin>>l1>>l2>>l3>>c1>>c2>>c3>>a>>b>>n){
		d=new int[n];
		d[1]=0;

		for(int i=2;i<=n;i++){
			cin>>d[i];
		}

		if(a>b)swap(a,b);
		l=d[b]-d[a];
		int ans;

		if(b-a==1){
			ans=cal(l);//如果ab是相邻的车站
		}
		else{
			int **dp=new int*[n+1];//如果ab不相邻
			for(int i=1;i<=n;i++)
				dp[i]=new int[n+1];
			for(int i=1;i<=n;i++){
				dp[i][i]=0;
				for(int j=i+1;j<=n;j++)
				{dp[i][j]=n*c3;}}//车站间的花费刚开始都设为最大
			for(int i=a;i<b;i++){dp[i][i+1]=cal(d[i+1]-d[i]);//计算相邻车站的花费
			
			}
			for(int len=2;len<=b-a;len++)//计算车站间隔为len的两个车站之间的最少花费
				for(int i=a;i+len<=b;i++){
					dp[i][i+len]=cal(d[i+len]-d[i]);//计算中途不停车从a开到b的花费作为初始值,如果距离大于l3,则设为不可达,即花费最大
					for(int k=i+1;k<i+len;k++)//挑选一个中间的车站
					{dp[i][i+len]=min(dp[i][i+len],dp[i][k]+dp[k][i+len]);//动态规划,保留最小花费

					}}
				ans=dp[a][b];

		}
		cout<<ans<<endl;











	}

	//freopen("CON","r",stdin);
	//system("pause");

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值