http://acm.timus.ru/problem.aspx?space=1&num=1170
大体解释在《算法艺术与信息学竞赛(第二版)》205页。
这个题目需要推算出一次导数(求导数零点)还有二次导数(判断极大极小),数学演算能力有限啊。。。公式推导了好久。。。
设斜率为k,若穿过改矩形,则可以按照205页四种情况算出a,b,给a,b加上标号编程ai,bi表示第i个矩形的a,b值,若没有穿过这个矩形,则ai = bi = 0;
用ci表示第i个矩形的时间参数,在矩形中走过的总时间为 T1 = ∑ci * (ai + bi / k) * √(1 + k ^ 2)
L表示总路程长度,cc表示不在矩形中的时间参数,不在矩形中的总时间为 T2 = cc * (L - ∑(ai + bi / k) * √(1 + k ^ 2))
总时间 y = T1 + T2;
可以抽取出关于ai的常数表达式,和关于bi的常数表达式
A = ai * (ci - cc) B = bi * (ci - cc)
y = T1 + T2
= (A + B / k) * √(1 + k ^ 2)
导数
dy = (A * k ^ 3 - B) / (√(1 + k ^ 2) * k ^ 3)
二次导数
ddy = (A * k ^ 3 + B * (3 * k ^ 2 + 2)) / (1 + k ^ 2) ^ (3 / 2)
代码中用 x1,x2,slp, slope_min 或 slope_max 代替斜率 k, 这些 x 和点坐标中的 x 需要加以区分,除了点结构体里面的x是表示点的 x 坐标,其余的 x 全部表示和上述函数 y 相关的自变量。
有一对全局变量 A, B
每次在斜率最相近的两个点间求出 A, B,然后在这两个点构成的区间 [x1, x2] 中求最小值
所有区间的最小值中最小的一个就是所求最小时间
这道题网上搜不到可以AC的代码,自己debug了很久才成功了,编码能力有待提高。呵呵。。。