HDOJ2059龟兔赛跑(动态规划,memset函数)

betball贝博app HDOJ 531 次浏览 , 没有评论

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

反正不断的去算到每一个充电点的最优时间。

解最优时间的过程中,要一个一个的往前找,判断前面的每一个充电点是否充电对到达该点时间的影响。因为有可能电池续航时间特别长,充一次电,10次充电点都不用再冲了。

然后就是要注意强制类型转换,起点处直接就满电。

学了一个memset函数,通过函数名可以看出来,内存赋值,直接给一大块内存置为同一个数。但是要注意一点,memset函数按字节对内存块进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)。

代码:

[cce_cpp]
/*100
3 20 5
5 8 2
10 40 60

0 10 20 30 40 50 60 70 80 90 100
  充       充    充
--------   --------------       若10处充电,为5*3+70/8+30/2
-----      --------------       10处不充电,为5*2+60/8+40/2
若在



100
3 60 5
5 8 2
10 40 60*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
/*
本题目包含多组测试,请处理到文件结束。每个测试包括四行:
第一行是一个整数L代表跑道的总长度
第二行包含三个整数N,C,T,分别表示充电站的个数,电动车冲满电以后能行驶的距离以及每次充电所需要的时间
第三行也是三个整数VR,VT1,VT2,分别表示兔子跑步的速度,乌龟开电动车的速度,乌龟脚蹬电动车的速度
第四行包含了N(N<=100)个整数p1,p2...pn,分别表示各个充电站离跑道起点的距离,其中0<p1<p2<...<pn<L
其中每个数都在32位整型范围之内。
*/
int main(){
	long long l, n, c, t, vr, vt1, vt2;
	long long p[101];//各个充电点距离起点的距离
	double rt, ttmp;//兔子的时间,和乌龟的时间的临时变量
	double tt[101];//乌龟到各个充电点的最短时间
	long long ts;
	int i, j,k;
	while (~scanf("%lld", &l)){
		scanf("%lld%lld%lld", &n, &c, &t);
		scanf("%lld%lld%lld", &vr, &vt1, &vt2);
		for (i = 1; i <= n; i++){
			scanf("%lld", &p[i]);
			tt[i] = 65535;
		}
		memset(tt,0, sizeof(tt));//填充值
		p[n + 1] = l;//终点
		tt[0] = 0; tt[n + 1] = 65535;
		p[0] = 0;
		rt = (double)l / vr;
		//从起点之外的第一个充电点处,向后依次来算到当前充电点的最短时间
		for (i = 1; i <= n + 1; i++){
			//求到每一个充电点的最短时间,需要计算从本充电点开始往前数,找到最短时间
			//52:要是上一个充电点在有电的状态中,怎么办?遍历到最一开始的充电点
			for (j = i-1; j >= 0; j--){
				if ((p[i] - p[j])>c)//充完电不足以跑完该小段
					ttmp = t + (double)c / vt1 + (double)((p[i] - p[j]) - c) / vt2;
				else
					ttmp = t+(double)(p[i] - p[j]) / vt1;
				if (j == 0)//起点免费充电
				{
					ttmp -= t;
				}
				if (tt[i] > (tt[j] + ttmp)){//从当前的判断点到该充电点的时间
					tt[i] = tt[j] + ttmp;
					//printf("在%lld点充电,到达%lld该点的时间为%lf\n", p[j], p[i], tt[i]);
					//如果确定在j点充电,要把充完电以后能走到的点的时间计算出来。
					
					k = i;
					while ((p[k] - p[j]) <= c&&p[k]<l){
						tt[k] = tt[j] +t+ (p[k] - p[j]) / (float)vt1;
						if (j == 0) tt[k] -= t;//注意判断是不是从起点出发的
						k++;
					}
					//想错了,52行根本不是问题,因为对于每一个点都要遍历到最一开始的充电点
							//if (p[k]<l)//再把停止后的第一个点的时间计算出来,解决52行提出的问题
							//tt[k] = tt[i - 1] + (p[k] - p[i - 1]) / (float)vt1;
				}
			}

		}
		if (tt[n + 1]<=rt)
			printf("What a pity rabbit!\n");
		else
			printf("Good job,rabbit!\n");
		//printf("%lf %lf\n", tt[n + 1],rt);
	}
	return 0;
}

[/cce_cpp]

发表评论

邮箱地址不会被公开。

Go