百练 / 2017研究生推免上机考试 E:Railway tickets

题目来源:http://poj.org/problem?id=2355

Railway tickets

-----------------------------------------------------

Time Limit: 1000MS

Memory Limit: 65536K

Total Submissions: 3418

Accepted: 1188

Description

The railway line"Ekaterinburg-Sverdlovsk" with several stations has been built. Thisrailway line can be represented as a line segment, railway stations beingpoints on it. The railway line starts at the station "Ekaterinburg"and finishes at the station "Sverdlovsk", so stations are numberedstarting from "Ekaterinburg" (it has number 1) and"Sverdlovsk" is the last station. 


Cost of the ticket between any two stations depends only on a distance betweenthem. The prices for the tickets are specified in the following table. 

distance between stations -X

price for the ticket

0<X<=L1

C1

L1<X<=L2

C2

L2<X<=L3

C3


Direct tickets from one station to another can be booked if and only if thedistance between these station does not exceed L3. So sometimes it is necessaryto book several tickets to pay for the parts of the whole way betweenstations. 

For example, on the railway line shown at the figure above there are sevenstations. The direct ticket from the second station to the sixth one can not bebooked. There are several ways to pay for the travel between these stations.One of them is to book two tickets: one ticket at price C2 to travel betweenthe second and the third stations, and other at price C3 to travel between thethird and the sixth stations. Note, that though the distance between the secondand the sixth stations is equal to 2*L2, the whole travel can not be paid bybooking two tickets at price C2, because each ticket is valid for only onetravel 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 travelbetween two given stations.

Input

The first line of the input file contains 6integers L1, L2, L3, C1, C2, C3 (1 <= L1 < L2 < L3 <= 10^9, 1 <=C1 < C2 < C3 <= 10^9) in the specified order with one space between.The second line contains the amount of stations N (2 <= N <= 10000). Thethird line contains two different integers separated by space. They representserial numbers of stations, the travel between which must be paid. Next N-1lines contain distances from the first station ("Ekaterinburg") onthe railway line to others. These distances are given as different positiveintegers and are arranged in the ascending order. The distance from"Ekaterinburg" to "Sverdlovsk" does not exceed 10^9. Thedistance between any neighboring stations does not exceed L3. The minimaltravel cost between two given stations will not exceed 10^9.

Output

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

Sample Input

3 6 8 20 30 40

7

2 6

3

7

8

13

15

23

Sample Output

70

-----------------------------------------------------

解题思路

一维动态规划问题(也可以看做二维动态规划解,但时间复杂度就超了)
难点:有3种票型,用3个双端队列维护距离当前计算节点小于等于票程的站点
这样时间复杂度O(n). 其实质是规避了向前搜索在票程之内的节点的查找过程。

-----------------------------------------------------

代码

// 算法:动态规划

/* 该版本借鉴了discuss中的思路,可以AC 
*/

#include
#include
#include
#include
#include
using namespace std;

int main()
{
    vector L;
    vector C;
    int i=0, tmp=0, j=0, k=0;
    for (i=0; i<3; i++)
    {
        cin >> tmp;
        L.push_back(tmp);
    }
    for (i=0; i<3; i++)
    {
        cin >> tmp;
        C.push_back(tmp);
    }
    int sN = 0;
    cin >> sN;                          // # of stations
    int src=0, dst=0;
    cin >> src >> dst;
    vector len;
    len.push_back(0);                   // 兼容始发站
    for (i=0; i> tmp;
        len.push_back(tmp);
    }

	if (dst == src)											// 始发站 = 终点站
	{
		cout << 0;
		return 0;
	}
	else if(dst < src)										// 始发站在终点站后面
	{
		swap(dst,src);
	}
	int m = dst - src;
    vector dp0;                                        // 动态规划数组0
	deque q[3];			// 辅助双向队列:距离(j+src-1)<=L[k]的站点(k=0,1,2)
	// initialization
	for (i=0; i<3; i++)
	{
		q[i].push_back(src-1);
	}
	dp0.push_back(0);
	for (i=1; i=dp0.at(j))
			{
				q[k].pop_back();
			}
			q[k].push_back(j+src-1);
		}
	}
	cout << dp0.at(m);
	
	return 0;
}


你可能感兴趣的:(百练OJ/poj)