时间限制: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;
}