题目大意:
给出直线上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尽可能减小就可以。