http://acm.hdu.edu.cn/showproblem.php?pid=2059
这个题用动态规划做。
问题:求到终点最短时间
因此,只要看乌龟和兔子到达终点的时间哪个短就行了。
兔子跑完全程用的时间很好求:time = L / VR
最主要的就是乌龟的最短时间。
我动态规划不是很懂,因此问了一下同学,给我讲解了一下,通过自己的理解,开始对动态规划有一点点感觉了。。
在这里,算乌龟的时间用动态规划,用dp[i]存储到达第i个充电站所用的最短时间,这里我们可以推导一下只有3个充电站的时候的情况:
在第二充电站时,有充电或者不充电到达dp[3]
两电站之间的距离 Len=p[3]-p[2]
不充电用时 : T2=Len/VT2;
充电用时: T1=T //把电充满所用的时间
当C< Len :T3=C/VT1+(Len-C)/VT2; //充电后走这段路用时
当C>= Len :T3=Len/VT2; //充电后走这段路用时
所以充电时总耗时T1 = T1+T3
所以又 DP[3]=DP[2]+min(T1,T2);
同理我们还要比较从dp[1],到dp[3],的情况;从dp[0],到dp[3],的情况。使其得到一个最短的DP[3];
通过代码慢慢理解这个。
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXX 999999
using namespace std;
double dp[110];
int main()
{
int l,n,c,t,vr,vt1,vt2;
int a[110],i,j,len;
double t1,t2,tm,time;
while(scanf("%d",&l)!=EOF)
{
for(i = 0; i < 110; i++)
{
dp[i] = MAXX;
}
scanf("%d%d%d",&n,&c,&t);
scanf("%d%d%d",&vr,&vt1,&vt2);
for(i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
}
a[0] = 0;
a[n+1] = l;
time = (double)l/vr; //兔子跑的时间
dp[0]=0.0;
for(i = 1; i <= n+1; i++) //求到第i个充电站的最少时间
{
for(j = 0; j < i; j++) //第j个充电站充电,其他都不充电
{
len = a[i]-a[j]; //两个充电站距离
t1 = t; //在第j个充电站充满电花的时间
t2 = ((double)len)/vt2;//在第j个充电站不充电到达第i个充电站所用时间
if(j == 0)
{
t1 = 0; //从起点出发不用充电
}
if(c >= len)
{
t1 += ((double)len)/vt1;
}
else
{
t1 += ((double)c)/vt1+((double)(len-c))/vt2;
}
tm = min(t1,t2);
// printf("tm==%.5lf\n",tm);
dp[i] = min(dp[i],dp[j]+tm);//到达第i个充电站的最短时间
}
// printf("i=%d time=%.5lf\n",i,dp[i]);
}
if(dp[n+1] < time)
{
printf("What a pity rabbit!\n");
}
else
{
printf("Good job,rabbit!\n");
}
}
return 0;
}