- 题目描述
一个特别的单行街道在每公里处有一个汽车站。顾客根据他们乘坐汽车的公里使来付费。例如下表就是一个费用的单子。 没有一辆车子行驶超过10公里,一个顾客打算行驶n公里(1< =n< =100),它可以通过无限次的换车来完成旅程。最后要求费用最少。 -
- 定义变量
题目中说明有需要10个整数代表不同路程的费用,于是先声明一个数组(名为worth,长度为11,worth[0]为空,worth[110]表示一次性行走110公里所需费用)
接着定义dp数组(dp[0] = 0),下标i为走过的总路程,dp[i]表示走过i公里所需的最小费用。
- 定义变量
- 求递推式
要走过i公里的路程,就需要分两步走,第一步是走i-j公里的路程,第二步是走j公里的路程(j <= i <= n(总路程), 0 <= j <= s(当i<=10时,s=i;否则s=10,下同))那么走过i公里的最小费用就是走过i-j公里的最小费用加上一次性走j公里所需的费用。
所以,令i从1到n循环,并将dp[i]初始化为INF=500*100+1=50001,以便比较得出最小值,再在这个循环中令j从1到s循环(当j=0时dp[i]=dp[i]+0可以省去),最里层不断比较dp[i]和dp[i-j]+worth[j]的大小并取小者储存于dp[i]中。
由此得到递推式:
dp[i] = min{dp[i-j] + worth[j], dp[i]}
- 代码说明
以下代码中MAX为最大总路程+1,A_JOURNEY为公共汽车一次性能行走的最大路程,INF用来初始化dp数组以便比较取最小费用。
#include<iostream>
#define MAX 101
#define INF 50001
#define A_JOURNEY 10
using namespace std;
inline int min(int a, int b) {
return a < b ? a : b;
}
int dp[MAX];
int main() {
int n, worth[A_JOURNEY + 1];
for(int i = 1; i <= A_JOURNEY; i++) //读入数据
scanf("%d", worth + i);
scanf("%d", &n);
for(int i = 1; i <= n; i++) { //i表示总路程
dp[i] = INF;
for(int j = 1; j <= (i <= A_JOURNEY ? i : A_JOURNEY);
j++) //j表示这班车走的路程
dp[i] = min(dp[i - j] + worth[j],
dp[i]); //dp[i]表示走i公里路程所需的最少费用
}
printf("%d", dp[n]);
return 0;
}
PS:本人不善于言辞,请多指教。