题目链接:https://vijos.org/p/1002
这题拿到手,很容易想到这样的一个dp方程:
f(i) = minof{f(i-j)+a[i]|j∈[s,t],且i-j>=0}
其中f(i)表示调到i位置最少需要的石子,a[i]表示i位置是否有石子,1表示有,0表示没有。
但是这题的L范围达到10^9,如果直接采用上面的dp方程只能拿到30分。
如何改进呢?我们很快注意到石子个数m最大不差过100,那么显然m个石子分布在很大的L上, 必然会存在相邻的石子距离非常大,那么f(i)会出现在较长的区间内值是一定的!
也就是说,这段很长的距离的f(i)值没必要继续一个个就算,因为这部分的f(i)和前面部分的f(i)是一样的,换句话说,其对答案没有贡献,只是起到一个“桥梁”、“传递”的作用,但是对我们来说,我们完全可以忽略这部分,直接跳到下一个石子!显然,如此一来,时间必然过得去。
那么忽略的部分是多少呢?换句话说,相邻石子距离压缩多少而不影响结果呢?当然我们希望越小越好。
那么我们只要知道多长距离以后,f(i)的值达到稳定。
上图中, x表示石子位置。其实从x+2T+1之后,f(i)开始稳定,所以我们最多只需要保留2*T的距离!
但是如果这样提交的话,我的程序只能拿到80分,有两个case过不去,发现都是s==t的case。
仔细想想,会发现,上面要想出现这种“传递"的作用,其实必须是局部可连续的,那么单s==t,就会导致所能跳达的点都是离散的,不符合前述的压缩做法。
所以加特判即可ac。详细代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include