1031. Railway Tickets(URAL 1031 )

51 篇文章 0 订阅
46 篇文章 1 订阅

1031. Railway Tickets

Time limit: 1.0 second
Memory limit: 64 MB
The railway line “Yekaterinburg-Sverdlovsk” with several stations has been built. This railway line can be represented as a line segment, railway stations being points on it. The railway line starts at the station “Yekaterinburg” and finishes at the station “Sverdlovsk”, so stations are numbered starting from “Yekaterinburg” (it has number 1) and “Sverdlovsk” is the last station.
Problem illustration
Cost of the ticket between any two stations depends only on a distance between them. The prices for the tickets are specified in the following table.
distance X between stationsprice for the ticket
0 < X ≤ L1C1
L1 < X ≤ L2C2
L2 < X ≤ L3C3
Direct tickets from one station to another can be booked if and only if the distance between these station does not exceed  L 3. So sometimes it is necessary to book several tickets to pay for the parts of the whole way between stations.
For example, on the railway line shown at the figure above there are seven stations. The direct ticket from the second station to the sixth one can not be booked. There are several ways to pay for the travel between these stations. One of them is to book two tickets: one ticket at price  C 2 to travel between the second and the third stations, and other at price  C 3 to travel between the third and the sixth stations. Note, that though the distance between the second and the sixth stations is equal to 2 L 2, the whole travel can not be paid by booking two tickets at price  C 2, because each ticket is valid for only one travel and each travel should start and end only at stations.
Your task is to write a program, that will find the minimal cost of the travel between two given stations.

Input

The first line of the input contains 6 integers  L 1L 2L 3C 1C 2C 3 (1 ≤  L 1 <  L 2 <  L 3 ≤ 10 9, 1 ≤  C 1 <  C 2 <  C 3 ≤ 10 9) in the specified order with one space between. The second line contains the amount of stations  N (2 ≤  N ≤ 10000). The third line contains two different integers separated by space. They represent serial numbers of stations, the travel between which must be paid. Next  N−1 lines contain distances from the first station (“Yekaterinburg”) on the railway line to others. These distances are given as different positive integers and are arranged in the ascending order. The distance from “Yekaterinburg” to “Sverdlovsk” does not exceed 10 9. The distance between any neighboring stations does not exceed  L 3. The minimal travel cost between two given stations will not exceed 10 9.

Output

Program should print to the output the only number, which is the minimal travel cost between two given stations.

Sample

input output
3 6 8 20 30 40
7
2 6
3
7
8
13
15
23
70
Problem Author: Pavel Zaletsky 
Problem Source: Ural Collegiate Programming Contest '99
Tags: dynamic programming  (hide tags for unsolved problems)
AC:
/*****************************************
在上图,整条铁路有七个站。从第2站不能直达第6站(因为距离大于L3),
但有另外几种方法购票。其中一种是买两张票:一张是从第2站至第3站(票价为C2),
另一张是从第3站至第6站(票价为C3),
注意,虽然从第2站至第6站的距离为2×L2,但不可以买两张价值C2的票,
因为一张票只可以用一次且起点和终点必须在车站上。

任务是:计算给出的两站之间的最小花费。

     -----DP-----
思路:
     设a[j]为j点到第一个点的距离。
     设dp[j]为到达j点时,最小的花费。
     对于途中任何一点j,其前面的点为k,start<=k<j,
       当a[j]-a[k]<=l1时,
       dp[j]=min(dp[k]+c1,dp[j]),start<=k<j;
       当a[j]-a[k]<=l2时,
       dp[j]=min(dp[k]+c2,dp[j]),start<=k<j;
       当a[j]-a[k]<=l3时,
       dp[j]=min(dp[k]+c3,dp[j]),start<=k<j.
这里,根据题意有个小优化:
       如果a[j]-a[k]<=l1,
       则就不需要考虑a[j]-a[k]<=l3的情况,
       因为,对应的c1小于c3。
根据这个,
       我们可以将k按照l1,l2,l3划分为三部分,
       第一部分只考虑c1,第二部分只考虑c2,
       第三部分只考虑c3.
       
代码如下:
*********************************************/
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAX 1000000000

using namespace std;

int n,st,en;
long long l[4],c[4];
long long a[10001]= {0},ans=MAX;
long long dp[10001]= {0};

void read()
{
    int i;
    scanf("%lld%lld%lld%lld%lld%lld",&l[1],&l[2],&l[3],&c[1],&c[2],&c[3]);
    scanf("%d",&n);
    scanf("%d%d",&st,&en);
    if(st>en)
    {
        int t;
        t=st;
        st=en;
        en=t;
    }
    for(i=2; i<=n; i++)
    {
        scanf("%lld",&a[i]);
        dp[i]=MAX;
    }
}

long long Min(long long a,long long b)
{
    if(a<b)
        return a;
    else
        return b;
}

void DP()
{
    int i,j,k;
    dp[st]=0;
    for(j=st+1; j<=en; j++)
        for(i=1,k=j-1; i<=3; i++)    /**优化部分,如此,便可以分成三部分**/
            for(k=k; k>=st; k--)       
            {
                if(a[j]-a[k]>l[i])
                    break;
                dp[j]=Min(dp[j],dp[k]+c[i]);
            }
}

void print()
{
    ans=dp[en];
    cout<<ans<<endl;
}

int main()
{
    //freopen("rail.in","r",stdin);
    //freopen("rail.out","w",stdout);
    read();
    DP();
    print();
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值