题目1086:最小花费 动态规划

题目描述:
在某条线路上有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 2 3 1 2 3
1 2
2
2
样例输出:
2

思路:首先想到的是用动态规划。用递归其实也可以,不过要最好用数组保存中间值,不然会超时

package 清华;

import java.io.BufferedInputStream;
import java.util.Scanner;

public class 最小话费1086 {

static long L[] = new long [3];
static long P[] = new long [3];
static int station[] ;
static long dist[];
public static void main(String[] args) {
Scanner s = new Scanner(new BufferedInputStream(System.in));
while(s.hasNextLong()){
for(int i=0; i<6; i++){
if(i>2)
P[i-3] = s.nextLong();
else
L[i] = s.nextLong();
}
int a = s.nextInt()-1;
int b = s.nextInt()-1;
int n = s.nextInt();
station = new int[n];
dist = new long[b-a+1];
for(int i=1; i<n; i++)
station[i] = s.nextInt();
f(a,b);
if(b-a>0)
System.out.println(dist[b-a]);
if(b==a)
System.out.println(0);
}
}
static void f(int a,int b){
for(inti=a+1; i<=b; i++){ //循环计算从起点开始到每个站的最小花费

int count = 0;
int x = i;
while(x-count-1 >=a && station[x]-station[x-count-1] <= L[2]) //计算本站前面不超过L3的站有几个

count ++;
long min = Long.MAX_VALUE;
for(int j=0; j<count; j++){ //依次算出 到本站的最小花费。 实用动态规划的思想。
min = Math.min(min,dist[i-j-1-a]+getP(station[i]-station[i-j-1]));
}
dist[i-a] = min;
}
}

static long getP(long len){
if(len == 0)
return 0;
else if(len <= L[0])
return P[0];
else if(len <= L[1])
return P[1];
else
return P[2];
}

}



原文地址:https://www.cnblogs.com/love533/p/2429200.html