旅游预算.cpp

<span style="color:#6600cc;">/*
一个旅行社需要估算乘汽车从某城市到另一城市的最小费用,沿路有若干加油站,每个加油站收费不一定相同。旅游预算有如下规则:若油箱的油过半,不停车加油,除非油箱中的油不可支持到下一站;每次加油时都加满;在一个加油站加油时,司机要花费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


By Yuanchang
2014.6.3
*/
#include<iostream>
#include<stdio.h>
using namespace std;
double length,capacity,kilometer,start;
int n,flag,mark[52],sum=0;
double oil[52][2],cost[52];
void Init()
{
    for(int i=0;i<=52;i++)
       {
        cost[i]=0;mark[i]=0;
       }
}

bool Canoil(int i,int j)//该加油站能不能加油
{
   double sum=oil[j][0]-oil[i][0];
    double remain=capacity-sum/kilometer;
    if(remain<=capacity/2){//cout<<i<<" "<<j<<endl;
    return 1;}
    return 0;
}

bool Mustoil(int i,int j)
{
    double sum=oil[j+1][0]-oil[i][0];
    if(capacity*kilometer<sum)
    {
    return 1;}
    return 0;
}

void res()
{
    int i,j;
    for(i=0;i<=n;)
       {if(mark[i]!=0)
        {sum++;
         i=mark[i];}
        else break;}
}

void Search()
{
    int i,j,k;
    double pay;
    int pri,end;
    for(i=n;i>=0;i--)//假设在第i个加油站加满油
      {flag=0;
          if(i==n)
            cost[i]=0;
       else{

             for(j=i+1;j<=n;j++)
             {
                 if(Mustoil(i,j)){
                     pay=cost[j]+(oil[j][0]-oil[i][0])/kilometer*oil[j][1]+2;
                     if(flag==0)
                       {
                           cost[i]=pay;
                           flag=1;
                           mark[i]=j;
                           j=n+1;
                       }
                     else if(pay<cost[i]){
                            cost[i]=pay; mark[i]=j;
                            j=n+1;}
                          }
                  else if(Canoil(i,j)){
                      pay=cost[j]+(oil[j][0]-oil[i][0])/kilometer*oil[j][1]+2;
                      if(flag==0)
                       {
                           cost[i]=pay;
                           flag=1; mark[i]=j;
                       }
                      else if(pay<cost[i]){
                            cost[i]=pay; mark[i]=j;}}
            }

      }
       }
}

void Print()
{int j,i;
   printf("%.2lf %d\n",cost[0]+start,sum);
   for(i=0;i<=n;){
     if(mark[i]!=0){
        cout<<mark[i];
        j=mark[i];
        i=j;
        if(i<=n)
          cout<<" ";
       }

      else break;
     }
       cout<<endl;
}

int main()
{
    scanf("%lf",&length);
    scanf("%lf %lf %lf %d",&capacity,&kilometer,&start,&n);
    for(int i=1;i<=n;i++)
      scanf("%lf %lf",&oil[i][0],&oil[i][1]);
      Init();
      oil[n+1][0]=length;
      oil[0][0]=0;
      Search();
       res();
      Print();
     // int m;scanf("%d",&m);
}









</span>


转载于:https://www.cnblogs.com/codeyuan/p/4254555.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值