hdu 2059 龟兔赛跑 dp

参考大牛的代码,
/*
这道题目是DP中多阶段决策的典型例题
我们将起点和终点划分到N个加电站中去
这样一共有N+2点,用DP[i]表示到第i个加电站的最小耗费时间
那么在求DP[i]的时候,DP[0]...DP[i-1]已经求得
让j从0遍历到i-1,每一个j表示最后一次充电到i点
那么状态转移方程为
DP[i] = min(DP[j] + t(j, i)) //t(j, i)表示从j充完电一直到i点(中途没有充过电)
*/

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<iomanip>

const int MAX=150;
const double INF=0xfffff;//0x代表十六进制
double DP[MAX];//DP[i]表示到第i个加电站的最小耗费时间
int s[MAX];//s[i]表示到第i个加电站距离起点的距离

using namespace std;

double Min(double x,double y)//判断大小
{
    return x>y?y:x;
}

int main()
{
    double L;
    int n,i,j;
    double electricity_l,electricity_t;
    double vt_rabbit,vt_ele,vt_none;
    double len,sum,Time;

    while(cin>>L)//输入跑道长度
    {
        cin>>n>>electricity_l>>electricity_t;//输入加电站的个数、电动车最大行驶距离、电动车的充电时间
        cin>>vt_rabbit>>vt_ele>>vt_none;//输入兔子、电动车、乌龟用脚踏的各个速度
        for(i=1;i<=n;i++)//输入各个加电站距离起点的位置
        cin>>s[i];
        s[n+1]=L;//把第n+1个加电站设为终点,长度为L
        s[0]=0;//把第0个加电站设为起点,长度为0
        DP[0]=0;//起点到起点最小耗费时间为0
        for(i=1;i<=n+1;i++)
        {
            DP[i]=INF;//因为到第i个加电站最小耗费时间未知所以赋值无穷大
            for(j=0;j<i;j++)
            {
                len=s[i]-s[j];//从第j个加电站到第i个加电站的距离
                if(len>electricity_l)//如果该距离大于电动车能行驶的最大距离
                Time=electricity_l/vt_ele+(len-electricity_l)/vt_none;//把电动车行驶的时间加上乌龟用脚踏的时间
                else//如果小于
                Time=len/vt_ele;//直接加上这段距离除于电动车的速度所得的时间
                Time+=DP[j];//之后加上到第j个加电站的最优时间
                if(j>0)//这里判断j>0是因为如果j==0的话,即表明从起点出发,因为起点已经充满电了所以不需要加上电动车的充电时间
                {
                    Time+=electricity_t;//如果j>0加上电动车的充电时间
                }
                DP[i]=Min(DP[i],Time);//每次挑出到第i个加电站的最优时间
            }
        }

        if(DP[n+1]<(L/vt_rabbit))//如果乌龟从起点到终点最小时间小于兔子的跑到终点的时间
        cout<<"What a pity rabbit!"<<endl;
        else
        cout<<"Good job,rabbit!"<<endl;
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值