4658: rescue
来源:互联网 发布:抢小米 软件 编辑:程序博客网 时间:2024/05/18 12:44
4658: rescue
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 47 Solved: 22
[Submit][Status][Discuss]
Description
wyh8000很喜欢看书,特别是那种很容易死脑细胞的书。
wyh8000看书喜欢从第K页开始看起,然后看到第M页,但是wvh8000并不是有耐心的小盆友,他
只想快点完成看书任务,然后就可以去愉快的农别人了,于是他经常跳着看,但是他一次最多跳D页,
然后阅读那一页的内容,然后死掉A的脑细胞。当然如果那一页的内容他比较感兴趣,又会回复一定
的脑细胞。
好心的学长不希望看到wyh8000的脑细胞死光,你能帮助wvh8000死掉尽可能少的脑细胞吗?
Input
第一行五个非负整数K,M,D,A,N。
K,M,D,A如题目描述。N表示有N页wvh8000比较感兴趣。
接下来N行,每一行两个正整数,Ti,Bi。,表示当wvh8000阅读第Ti页时,能回复Bi的脑细胞。
l <= Bi,A,D≤10^9,l<N<105。0<=K<T1<T2<…<Tn<M <= 10^9。
Output
一个整数ans。表示能拯救的最多的脑细胞数,若最后还是损失则为负数。
Sample Input
0 10 4 10 2
3 10
8 5
3 10
8 5
Sample Output
-20
wyh8000从第0页开始看。
wyh8000跳到第3页,损失10脑细胞。
wyh8000阅读第3页,拯救10脑细胞。
wyh8000跳到第7页并阅读,损失10脑细胞。
wyh8000眺到第10页并阅读,损失10脑细胞。
学长最后无能为力,但是损失20是最优的策略,所以输出为-20。
wyh8000从第0页开始看。
wyh8000跳到第3页,损失10脑细胞。
wyh8000阅读第3页,拯救10脑细胞。
wyh8000跳到第7页并阅读,损失10脑细胞。
wyh8000眺到第10页并阅读,损失10脑细胞。
学长最后无能为力,但是损失20是最优的策略,所以输出为-20。
HINT
Source
有用的页数显然就是那N个关键页
定义f[i]:看到第i个关键页时,脑细胞最大剩余量
f[i] = max{f[k] - A * [(T[i] - T[k]) / D]} + B[i] (k = 1~i-1,[]为上取整)
注意到[(T[i] - T[j]) / D] 和 [T[i] / D] - [T[j] / D] 的值几乎是一样的(最多相差1)
当T[i] % D > T[j] % D后式的结果会比预期大1
所以将T[i]的值按照%D分类,转移的时候分两类用线段树维护max即可
注意到转换之后[T[i] / D] - [T[j] / D]是个差分的形式,所以加到最后中间项都抵消了
那么只需要最后减去A * ([M / D] - [K / D]),中间讨论是否差1即可
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>#include<cmath>#include<stack>#define max(a,b) ((a) > (b) ? (a) : (b))using namespace std; const int N = 4;const int maxn = 1E5 + 10;typedef long long LL;const LL INF = 1E16; int n,m,K,D,cur = 1,T[maxn],B[maxn],w[maxn];LL A,f[maxn],Max[maxn*N],ma[maxn]; inline void Build(int o,int l,int r){ Max[o] = -INF; if (l == r) {ma[l] = -INF; return;} int mid = l + r >> 1; Build(o<<1,l,mid); Build(o<<1|1,mid+1,r);} inline void Modify(int o,int l,int r,int pos,LL now){ Max[o] = max(Max[o],now); if (l == r) return; int mid = l + r >> 1; if (pos <= mid) Modify(o<<1,l,mid,pos,now); else Modify(o<<1|1,mid+1,r,pos,now);} inline LL Query(int o,int l,int r,int ql,int qr){ if (ql <= l && r <= qr) return Max[o]; int mid = l + r >> 1; LL ret = -INF; if (ql <= mid) ret = Query(o<<1,l,mid,ql,qr); if (qr > mid) ret = max(ret,Query(o<<1|1,mid+1,r,ql,qr)); return ret;} inline int getint(){ char ch = getchar(); int ret = 0; while (ch < '0' || '9' < ch) ch = getchar(); while ('0' <= ch && ch <= '9') ret = ret * 10 + ch - '0',ch = getchar(); return ret;} int main(){ #ifdef DMC freopen("DMC.txt","r",stdin); #endif cin >> K >> m >> D >> A >> n; for (int i = 2; i <= n + 1; i++) T[i] = getint(),w[i] = getint(),B[i] = T[i] % D; B[1] = K % D; B[n + 2] = m % D; T[1] = K; T[n + 2] = m; n += 2; sort(B + 1,B + n + 1); for (int i = 2; i <= n; i++) if (B[i] != B[i - 1]) B[++cur] = B[i]; Build(1,1,cur); int pos = lower_bound(B + 1,B + cur + 1,T[1] % D) - B; Modify(1,1,cur,pos,0); ma[pos] = 0; for (int i = 2; i <= n; i++) { pos = lower_bound(B + 1,B + cur + 1,T[i] % D) - B; LL x = Query(1,1,cur,pos,cur); LL y = pos == 1 ? -INF : Query(1,1,cur,1,cur - 1); f[i] = max(x,y - A) + 1LL * w[i]; if (f[i] > ma[pos]) Modify(1,1,cur,pos,f[i]),ma[pos] = f[i]; } cout << f[n] - 1LL * (T[n] / D - T[1] / D) * A << endl; return 0;}
0 0
- 4658: rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- Rescue
- 一种优化组合相似度的协同过滤推荐算法
- 使用Java实现面向对象编程--集合框架-->迭代器Iterator
- C++中静态初始化数组与动态初始化数组
- 递归递推 C
- EasyUI之滑动条Slider
- 4658: rescue
- linux复制与粘贴操作的快捷键
- java 多线程概要
- 一个Windows下的tail工具(即时查看日志)
- JS--addEventListener()
- VectorDrawable矢量图
- java 中的抽象方法
- 欢迎使用CSDN-markdown编辑器
- 用户登录记住密码