Pogo-Cow

题目大意:

给出直线上N个点的坐标和分数,任意选一个点出发,每次只能跳到另外一个点上并获得相应的分数,且每次跳的方向要相同,本次跳的距离不小于上次跳的距离。  求最大得分。   N<=1000.

解题过程:

1.借鉴了lsdsjy大牛的O(N^2logN)的方法,二分非常巧妙。http://www.cnblogs.com/lsdsjy/p/4032011.html

下面说说往右跳的方法(往左跳是一样的道理,只要把点的坐标相反数一下,然后重新排序,复制往右跳的代码就好)

F[i][j]  (i<j) 表示最后一次跳跃是从i跳到j的最优解.

那么F[i][j]=max{F[k][i]}+val[j].  (dist[i]-dist[k]<=dist[j]-dist[i]) 复杂度是O(N^3) 显然不够快。

那么可以用一个辅助数组g[i][j]来记录max{ F[i...j-1][j] }.  显然g[i][j]随着i的减小而增大

那么对于F[i][j],只要二分找到最小的k,满足dist[i]-dist[k]<=dist[j]-dist[i],那么F[i][j]=g[k][i]+val[j]。

为了方便维护g数组,外层循环为j (1 to N),内层循环为i (j-1 to 1).

2.其实还有更好的O(N^2)算法。 F[i][j]的含义同上。

注意到当j固定时,随着i的减小,需要找到的k也是不断减小的,所以没有每次必要二分找到k,只要每次i减小的时候,让k尽可能减小就可以。

原文地址:https://www.cnblogs.com/vb4896/p/4037919.html