HDU2059 龟兔赛跑(多决策的动态规划)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2059

分析:

兔子跑完全部路程的时间是定值,主要看乌龟如何走完全程,且用时最短。用这个最短的时间和兔子的时间相比。

首先我们可以把起点和终点都当作充电站,这样一共就有n+2个充电站,特殊情况是起点的充电站给车子充满电是不需要时间的,所以这个情况需要特判一下就是dp[0] = 0. 我们最终的目标是到达终点处的充电站所需要的时间最短。

接下来我们来推到状态转移方程,假设当前充电站是 i ,然后我们要枚举 0 - i-1个充电站,每个充电站选择充还是不充表达式为:dp[i] = min(dp[i], dp[j]+x, dp[j]+y])
x表示在第j个充电站充完电然后开到 i 所用的时间(中途不再充电)
y表示在第j个充电站不充电,直接开到 i 所用的时间

PS:当然这里dp[j]+y实际不必要考虑,因为你在j-1号充电站判断是不是要充电的时候已经把在J号充电站不充电的情况考虑进去了。所以加不加问题不大,思路都是正确的。加了更容易理解,如果你熟练了以后可以直接去掉。

code:

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>

using namespace std;
const int INF = 0x3f3f3f3f;

double dp[100+7];
int dis[100+7]; // 每个充电站到起点的距离

int main()
{
    int l;
    while(scanf("%d", &l) != EOF)
    {
        int n, c, t;    // 充电站的个数,充完电行驶的距离,充电所需时间
        int vr, vt1, vt2; // 兔子的速度,骑车速度,脚蹬速度
        scanf("%d %d %d", &n, &c, &t);
        scanf("%d %d %d", &vr, &vt1, &vt2);

        dis[0] = 0;
        dis[n+1] = l;
        for(int i=1; i<=n; i++)
            scanf("%d", &dis[i]);
        // memset(dp, 0x3f, sizeof(dp)); double类型不能用memset 
        dp[0] = 0;
        for(int i=1; i<107; i++)
            dp[i] = INF;
        
        double tmp;
        for(int i=1; i<=n+1; i++)   // 先枚举1到n+1个充电站
        {
            for(int j=0; j<i; j++)   // 枚举当前充电站之前的充电站
            {
                int len = dis[i] - dis[j];  // 两个充电站之间的距离
                if(len <= c)
                    tmp = 1.0 * len / vt1;
                else
                    tmp = 1.0 * c/vt1 + 1.0 * (len-c) / vt2;
                if(j != 0)  // 因为考虑从的是在j充电站充电所以要加上充电的时间
                    tmp += t;
                dp[i] = min(dp[j]+tmp, dp[i]);
            }
        }
        double tr = 1.0 * l /vr;    // 兔子所用时间
        if(dp[n+1] > tr)
            printf("Good job,rabbit!\n");
        else
            printf("What a pity rabbit!\n");
    }


    return 0;
}

 

全部评论

相关推荐

2025-12-06 01:10
已编辑
哈尔滨工程大学 Java
一面问的真细,二面不知为啥变双机位。9.29快手主站平时怎么学习&nbsp;AI&nbsp;的,国内外知名大模型,实习公司都用的什么大模型,怎么评估效果的java池化思想,线程池构造方法的核心参数,线程池中阻塞队列注意事项,submit方法参数和执行逻辑,shutdown和shutdownnow,核心线程允许过期吗threadlocal底层,为什么key是弱引用,key回收了再get或者set这个value会怎样aqs,如何保证公平性java代理java堆划分,新生代还有别的晋升老年代的情况吗,什么时候触发gc,gc失败抛什么异常,如何排查oom,导出dump命令redis数据结构,哪个底层是跳表,和其他数据结构对比布隆过滤器会出现大key问题吗,你咋实现的布隆过滤器你怎么实现redis分布式锁,可重入,续期聚簇索引非聚簇索引select语句会加锁吗,怎么实现的不加锁undolog&nbsp;redolog&nbsp;binlog怎么能让select加锁,update这个范围加的什么锁,update一条呢手撕简单01背包,接雨水10.10快手主站意图识别用的哪个大模型,走到意图和rag的比例,faq是点击的吗自然语言怎么识别的gap一年干啥了,转正怎么样没跟组里提意向吗,研究生研究方向是传统算法吗,会大模型微调吗注册场景为什么用布隆过滤器,原理分布式锁底层的key怎么拼的,value里是什么redis持久化zset底层mysql索引结构,一个表三个字段有主键唯一索引和没索引的字段会有几个b+树,聚簇索引非聚簇索引存的啥无手撕
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务