动态规划求解 最小花费

题目1086:最小花费

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:2082

解决:398

题目描述:
在某条线路上有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
#include <iostream>
using namespace std;
#define MAX 100000000000
typedef long long int64;
int64 l1,l2, l3, c1, c2, c3;
int64 arr[10000]; //存储i 到 i-1 的距离

int64 a,b;
int64 n;
int64 ans = MAX;
int64 cost[10000]; //存储最优花费

int64 getP(int64 l){
	if(l == 0)
		return 0;
	else if(l <= l1)
		return c1;
	else if(l <= l2)
		return c2;
	else
		return c3;
}

//从a到k的最优解,依赖于a到k-1的最优解。
void solve(int64 a,int64 b){
	int64 len = b-a + 1;
	for(int64 i=0; i<= len; i++)
		cost[i] = MAX;
	cost[0] = 0;
	int64 tmp;
	for(int i=a+1; i<=b; i++){
		int64 k = i; //当前遍历到的位置
		int64 cnt = 0;
		int64 sum = arr[k];

		//再往前遍历cnt个位置, 得到该位置的最优解
		while(sum <= l3 && k-cnt > a){
			cnt ++;
			tmp = cost[k-a-cnt] + getP( sum );
			if(cost[k-a] > tmp)
				cost[k-a] = tmp;
			sum += arr[i-cnt];
		}
	}
}

int main(){
	while(cin >> l1 >> l2 >> l3 >> c1 >> c2 >> c3)
	{
		cin >> a >> b >> n;
		if(a > b){
			swap(a,b);
		}
		int64 pre = 0,cur;
		for(int64 i=2; i<=n; i++)
		{
			cin >> cur;
			arr[i] = cur - pre;
			pre = cur;
		}
		if(a == b)
			cout << 0 << endl;
		else{
			solve(a,b);
			cout << cost[b - a] << endl;
		}
	}

	return 0;
}




下面还有用Java写的递归版本。

import java.io.BufferedInputStream;
import java.util.Scanner;
 
public class Main{
     
    static long L[] = new long [3];
    static long P[] = new long [3];
    static int station[] ;
    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];
            for(int i=1; i<n; i++)
                station[i] = s.nextInt();
             
            System.out.println(f(a,b));
        }
             
    }
    private static long f(int a, int b) {
        long len = station[b]-station[a];
         
        if(b == a)
            return 0;
        else if(b-a == 1)
            return getP(len);
 
        else{
            if(station[b]-station[b-1] < L[2])
                return Math.min(f(a,b-1)+getP(station[b]-station[b-1]), f(a,b-2)+getP(station[b]-station[b-2]));
            else
                return f(a,b-1)+getP(station[b]-station[b-1]);
        }
             
    }
     
    static long getP(long len){
        if(len == 0)
            return 0;
        else if(len <= L[0])
            return P[1];
        else if(len <= L[1])
            return P[1];
        else
            return P[2];
    }
 
}


你可能感兴趣的:(动态规划求解 最小花费)