http://acm.hust.edu.cn:8080/judge/problem/viewProblem.action?id=23094
Brief description:
。。。某个工厂同一时刻最多只可以装载一种机器,
。。。机器有买入价格,卖出价格,和每日利润。
。。。有 n 个可以买入机器的时点。。每个时点形如,d, p, r, g 。。。
。。。分别表示时刻,买入价格,卖出价格和该机器的日利润。
。买入只能在那个时刻进行,而卖出可以选择买入后的任意时刻。
。给定初始时刻的金币,问 d 天后所能获得金币的最大值。
Analysis:
原题中的两个不太自然的条件。。
1. 任何时刻只能保留至多一台机器。
2. 机器卖出的收益是固定的,与日期无关。。
综合上述两个条件不难得到 O(n2) 的暴力 DP。。。
http://acm.hust.edu.cn/vjudge/problem/viewSource.action?id=2838582
//}/* .................................................................................................................................. */
const int N = int(1e5) + 9;
LL f[N];
struct Event{
int d,p,r,g; // 买入时间,买入价格,卖出价格,日利润。
bool operator <(const Event& rhs)const{
return d < rhs.d;
}
void in(){
RD(d,p,r,g);
}
} E[N];
int n, d;
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
while (RD(n, f[0], d)){
REP_1(i, n) E[i].in(); sort(E+1, E+n+1); ++n; E[n].d = d+1; E[n].p = E[n].g = 0;
// b = kx + y
#define k (LL)E[i].d
#define x E[j].g
#define y (f[j]+E[j].r-E[j].p-(LL)x*(E[j].d+1))
REP_1(i, n){
f[i] = f[i-1]; REP(j, i) if (f[j] >= E[j].p){
checkMax(f[i], k*x + y);
}
}
OT(f[n]);
}
}
写成斜率 DP 的标准形式,注意到这里 k, x 均不单调,无法使用单调队列优化。。
方法一:
Splay 维护凸壳。
http://acm.hust.edu.cn/vjudge/problem/viewSource.action?id=880923 (注意用叉积。。。
500ms O(nlogn)
方法二:
cdq 分治
洲妹告诉我们。。这类问题都可以用 cdq 分治来解决。。。
。。。
通过 cdq 分治。。将原本需要强制在线的询问。。可以离线处理。。。于是可以通过排序、重新让询问单调。。
。。重新让栈随便搞搞就能解决、、。。。。。。。。从而极大的降低了编程难度。。
http://acm.hust.edu.cn/vjudge/problem/viewSource.action?id=2795801
(1640ms。。。O(nlog2n)




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
