旅游预算

时限:1000ms 内存限制:10000K 总时限:3000ms

描述:

一个旅行社需要估算乘汽车从某城市到另一城市的最小费用,沿路有若干加油站,每个加油站收费不一定相同。旅游预算有如下规则:若油箱的油过半,不停车加油,除非油箱中的油不可支持到下一站;每次加油时都加满;在一个加油站加油时,司机要花费2元买东西吃;司机不必为其他意外情况而准备额外的油;汽车开出时在起点加满油箱;计算精确到分(1元=100分)。编写程序估计实际行驶在某路线所需的最小费用。

输入:

第一行为起点到终点的距离(实数)第二行为三个实数,后跟一个整数,每两个数据间用一个空格隔开。其中第一个数为汽车油箱的容量(升),第二个数是每升汽油行驶的公里数,第三个数是在起点加满油箱的费用(精确到分),第四个数是加油站的数量。(〈=50)。接下去的每行包括两个实数,每个数据之间用一个空格分隔,其中第一个数是该加油站离起点的距离,第二个数是该加油站每升汽油的价格(元/升)。加油站按它们与起点的距离升序排列。所有的输入都有一定有解。

输出:

共两行,每行都有换行第一行为一个实数和一个整数,实数为旅行的最小费用,以元为单位,精确到分,整数表示途中加油的站的N。第二行是N个整数,表示N个加油的站的编号,按升序排列。数据间用一个空格分隔,最后一个数据后也输出空格,此外没有多余的空格。

输入样例:

516.3

15.7 22.1 20.87 3

125.4 1.259

297.9 1.129

345.2 0.999

输出样例:

38.09 1

2

#include<cstdio>
#include<iostream>
#include<algorithm>
#define INF 1000000000.0
using namespace std;

double L;
double v,dx,fp;
int n;
double x[60],p[60];
double dp[60];
int after[60];

void run()
{
	for(int i=0;i<n;i++)
	{
		dp[i]=INF;
	}
	dp[n]=dp[n+1]=0.0;

	for(int i=n;i>=0;i--)
	{
		for(int j=i+1;j<=n+1;j++)
		{
			double dv=(x[j]-x[i])/dx;
			if(dv<0.5*v)
			{
				if(j<=n && (x[j+1]-x[i])/dx<=v)
				{
					continue;
				}
			}
			if(dv>v) {break;}

			if(j!=n+1)
			{
				if(dp[j]+p[j]*dv+2.0<dp[i])
				{
					dp[i]=dp[j]+p[j]*dv+2.0;
					after[i]=j;
				}
			}
			else
			{
				if(dp[j]<=dp[i])
				{
					dp[i]=dp[j];
					after[i]=j;
				}
			}
		}
	}
}

void Route()
{
	int cur=0,cnt=0;
	while(after[cur]!=n+1)
	{
		cnt++;
		cur=after[cur];
	}
	printf("%d\n",cnt);

	cur=0;
	while(after[cur]!=n+1)
	{
		printf("%d ",after[cur]);
		cur=after[cur];
	}
	printf("\n");
}

int main()
{
	scanf("%lf",&L);
	scanf("%lf%lf%lf%d",&v,&dx,&fp,&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lf%lf",&x[i],&p[i]);
	}
	x[0]=0.0;
	x[n+1]=L;
	run();
	printf("%.2lf ",dp[0]+fp);
	Route();
	return 0;
}
发布了105 篇原创文章 · 获赞 53 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/zhao2018/article/details/83420944