一、原题目
1.题目描述
一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里使来付费。例如下表就是一个费用的单子。没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1<=n<100),它可以通过无限次的换车来完成旅程。最后要求费用最少。
2.输入
第一行十个整数分别表示行走1到10公里的费用(<=500)。注意这些数并无实际的经济意义,即行驶10公里费用可能比行驶一公里少。第二行一个整数n表示,旅客的总路程数。
3.输出
仅一个整数表示最少费用。
4.样例输入
12 21 31 40 49 58 69 79 90 101
15
5.样例输出
147
二、题目分析
-
简单动态规划。使用 d p [ i ] dp[i] dp[i]表示从起点行驶到第 i i i公里处需要的最小花费。
-
考虑行驶到第 i i i公里前一站——第 j j j公里处的最小花费是 d p [ j ] dp[j] dp[j],那么从起点直接行驶到 i i i公里处的一个可能花费 t e m p temp temp为:
t e m p = d p [ j ] + c o s t ( j − i ) temp = dp[j] + cost(j - i) temp=dp[j]+cost(j−i)
其中, c o s t ( x ) cost(x) cost(x)表示从车站坐车行驶 x x x公里 ( 1 < = x < = 10 ) (1 <=x<=10) (1<=x<=10)的花费。 -
对于 d p [ i ] dp[i] dp[i],只需要求出上式在 j = i − 10 j = i - 10 j=i−10 到 j = i − 1 j = i - 1 j=i−1之间的最小值即可,即:
d p [ i ] = min i − 10 < = j < = i − 1 { d p [ j ] + c o s t ( j − 1 ) } dp[i] = \min_{i-10 <= j <=i-1}{\{dp[j] + cost(j - 1)}\} dp[i]=i−10<=j<=i−1min{dp[j]+cost(j−1)}
三、代码
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int cost[11];
for(int i = 1; i <= 10; i++)
cin >> cost[i];
int n;
cin >> n;
int dp[110];
for(int i = 1; i <= n; i++)
dp[i] = cost[i];
for(int i = 2; i <= n; i++){
dp[i] = i > 10 ? int(pow(2, 16)) : dp[i];
for(int j = 1; j < i; j++){
int temp = dp[j] + dp[i - j];
if(temp < dp[i])
dp[i] = temp;
}
}
cout<<dp[n]<<endl;
return 0;
}