【9914】最小乘车费用

Time Limit: 3 second
Memory Limit: 2 MB

【问题描述】

某条街上每一公里就有一汽车站,乘车费用如下表:
公里数 1 2 3 4 5 6 7 8 9 10
费用 12 21 31 40 49 58 69 79 90 101

而一辆汽车从不行驶超过10公里。某人想行驶n公里,假设他可以任意次换车,请你帮他找到一种乘车方案使费用最小(10公里的费用比1公里小的情况是允许的)。

【输入格式】

第一行为10个不超过100的整数,依次表示行驶1~10公里的费用,相邻两数间用空格隔开。第二行为某人想要行驶的公里数。

【输出格式】

仅一行,包含一个整数,表示该测试点的最小费用。

【输入样例】

    12 21 31 40 49 58 69 79 90 101
    15

【输出样例】

    147
【题解】
设f[j]表示到j公里处,所需的最小花费。
f[j] = min (f[j],f[j-i] + cost[i]),i是公里数(1..10),cost[i]表示走i公里的花费。
即如果更新了f[j],则从f[j-i]处进行一次换车。
这很像背包问题。
到了第5公里,前4公里的最优值就与第1公里的无关了,而第5公里的最优值可以由前面的最优值推出。
一开始所有的f值都为一个很大的数,除了f[0]外。f[0] = 0表示走0公里不要花费。
【代码】
#include <cstdio>

int cost[11],f[100000],m;

void input_data()
{
	for (int i = 1;i <= 10;i++)
		scanf("%d",&cost[i]);
	scanf("%d",&m);
}

void get_ans()
{
	for (int i = 1;i <= m;i++) //一开始所有值都赋成一个很大的值。 
		f[i] = 2100000000/3;
	f[0] = 0; //走0公里花费为0; 
	for (int j = 1;j <= m;j++) //对m公里的路进行DP(动态规划是一个动词 嗯。。) 
		for (int k = 1;k <= 10;k++)
			{
				if (j - k < 0) break; //如果未满10公里 则要break掉。后面k
				//越来越大所以可以break掉.break只break一层循环 
				if (f[j] > f[j-k] + cost[k])
					f[j] = f[j-k] + cost[k];
			}
}

void output_ans()
{
	printf("%d",f[m]);
}

int main()
{
	//freopen("F:\\rush.txt","r",stdin);
	input_data();
	get_ans();
	output_ans();
	return 0;
}



posted @ 2017-10-06 19:23  AWCXV  阅读(235)  评论(0编辑  收藏  举报