2364: 【入门】公交乘车
内存限制:128 MB
时间限制:1.000 S
评测方式:文本比较
命题人:
提交:3
解决:3
题目描述
A城市有一条非常特别的街道,该街道在每个公里的节点上都有一个公交车站,乘客可以在任意的公交站点上车,在任意的公交站点下车。乘客根据每次乘坐公交的公里数进行付费,比如,下表就是乘客乘坐不同的公里数要付的费用。(请注意:不一定公里数越高,费用越高,这也是这条街道特别的地方)
| 公里数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 付费金额 | 12 | 21 | 31 | 40 | 49 | 58 | 69 | 79 | 90 | 101 |
一辆公交车单次行驶的公里数一定不超过 10 公里,一个乘客如果打算乘坐公交车完成 n 公里(1≤n≤100)的行程,他可以选择无限次的换车来完成行程。
请问,他最少要花多少钱?
输入
第一行十个整数分别表示公交行走 1 到 10 公里的费用(≤500)。注意这些数并无实际的经济意义,即行驶 10 公里费用可能比行驶一公里少。
第二行一个整数 n 表示,旅客的总路程数。(1≤n≤100)
输出
仅一个整数表示最少费用。
样例输入 复制
12 21 31 40 49 58 69 79 90 101
15
样例输出 复制
147
提示
完全背包问题
- 要走总共 n 公里,可以无限次换车。
-
每次乘车可以选走
1~10公里;走 k 公里花费对应输入的费用。 - 目标:凑齐总 n 公里,总花费最小。
状态定义: dp[i]:走完 i 公里 需要的最少花费。
转移方程:
对于每一个总里程i,尝试走 k 公里(k=1~10,i>=k)
\(dp[i]=\min(dp[i],\ dp[i-k] + cost[k])\)
初始化:
-
dp[0]=0:0 公里花费 0; - 其余 dp 数组初始化为很大的数(无穷大)。
cost [1] 是走 1 公里费用,cost [2] 走 2 公里……cost [10] 走 10 公里。
#include <iostream>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 105;
int dp[MAXN];
int cost[11]; // cost[1]~cost[10]
int main()
{
for(int i = 1; i <=10; i++)
{
cin >> cost[i];
}
int n;
cin >> n;
//初始化无穷大
for(int i = 1; i <= n; i++)
dp[i] = INF;
dp[0] = 0;
//完全背包
for(int i = 1; i <= n; i++)
{
//尝试每一种单次乘车距离1~10
for(int k = 1; k <= 10; k++)
{
if(i >= k)
{
dp[i] = min(dp[i], dp[i - k] + cost[k]);
}
}
}
cout << dp[n] << endl;
return 0;
}