杭电2059--龟兔赛跑

题目描述:
这里写图片描述

解析:
使用动态规划思想建立模型,开始以为自己对动态规划已经很熟练了,做了这道题才发现,呵呵~还是得练!
废话不多说,这道题的思想如下:
想要求乌龟与兔子谁先到达终点,其实就是拿乌龟到达终点的最快速度与兔子的相比,因此我们设乌龟到达某一点最快的时间为dp[n],对于每过一个点,存在充电与不充电两种情况,因此我最初的想法是比较充电与不充电这两种情况的最短时间,作为dp[i]。然而真正写完才发现,不充电的情况下,还需要知道在这种情况下,乌龟从上一个点出发时电动车的电还能支持它走多远,很麻烦~
借鉴了网上的代码和思路,才发现自己的想法太刻板。如果能确定在最优解的情况下,最近一次充电是什么时候,就能知道相对的整体最优解。因此我们加一层循环来表示之前的某个点到i点的最短时间,通过比较得出dp[i],进而求出整体的最优解。
如果上一次充电的地点和这一次充电地点的距离比C要长,证明需要脚蹬,因此:

                if(a[i]-a[j]>c)
                    time=1.0*c/vt1+1.0*(a[i]-a[j]-c)/vt2;

否则的话,这两点间全程都可以以最快速度走完:

                else
                    time=1.0*(a[i]-a[j])/vt1;

同时考虑到初始站点并不需要充电,写出代码:

//杭电龟兔赛跑
#include<stdio.h>
#include<string.h>
#define MAXN 100005
#define min(a,b) (a<b?a:b)
int main()
{
    int l,n,c,t,i,j,k;
    int vr,vt1,vt2,cnt,a[MAXN];
    float dp[MAXN],time,timer;
    while(scanf("%d",&l)!=EOF&&l)
    {
        scanf("%d%d%d",&n,&c,&t);
        scanf("%d%d%d",&vr,&vt1,&vt2);
        dp[0]=a[0]=0;
        a[n+1]=l;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(i=1;i<=n+1;i++)
        {
            dp[i]=MAXN; 
            for(j=0;j<i;j++)
            {
                if(a[i]-a[j]>c)
                    time=1.0*c/vt1+1.0*(a[i]-a[j]-c)/vt2;
                else
                    time=1.0*(a[i]-a[j])/vt1;
                dp[i]=min(dp[i],dp[j]+time+t*(j>0));
            }
        }
        timer=(float)l/vr;
        if(timer<dp[n+1])
            printf("Good job,rabbit!\n");
        else
            printf("What a pity rabbit!\n");
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/cprimesplus/article/details/82627640