HDU 2059 龟兔赛跑
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; }