傻傻的NBC好久没更博啦.
似乎荒废了.
要这博客何用..
好吧好吧切入正题
f[x]
表示(最后读的一页是(第x个感兴趣的页)时拯救的最多脑细胞数量)
方便起见令
T[0]=K,T[N+1]=M,B[0]=B[N+1]=0
最终答案是
f[N+1]
f[x]=maxx−1i=0f[i]+ceil((T[x]−T[i])/D)∗A
于是得到了 O(N2) 的算法
#include <cstdio>
long long f[100002];
int K, M, D, A, N, T[100002], B[100002];
inline long long max(long long x, long long y)
{
return x > y ? x : y;
}
int main()
{
scanf("%d%d%d%d%d", &K, &M, &D, &A, &N);
T[0] = K, T[N + 1] = M;
for (int i = 1; i <= N; i++)
scanf("%d%d", T + i, B + i);
for (int i = 1; i <= N + 1; i++)
{
f[i] = -1ll << 62;
for (int j = 0; j < i; j++)
f[i] = max(f[i], f[j] - (T[i] - T[j] + D - 1) / D * A);
f[i] += B[i];
}
printf("%lld\n", f[N + 1]);
return 0;
}
现在睁大你可爱的小眼睛盯着这个可爱的DP方程30秒
f[x]=maxx−1i=0f[i]+ceil((T[x]−T[i])/D)∗A
ceil((T[x]−T[i])/D) 变成什么比较好呢…
ceil((T[x]−T[i])/D)=T[x]/D−T[i]/D+[T[x] mod D>T[i] mod D]
原DP方程biu~~一下变成了
f[x]=max(max0<=i<x且T[i] mod D<T[x] mod D(f[i]+T[i]/D∗A−A),max0<=i<x且T[i] mod D>=T[x] mod D(f[i]+T[i]/D∗A))−T[x]/D∗A
// 其中除号是整除,请委屈地捏着鼻子看完
对着 T[i] mod D 建出线段树,每次在线段树的 T[i] mod D 位置插入 f[i]+T[i]/D∗A
啊好简单,为什么要写那么简单的题的题解呢
因为我只会做简单题呀