博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LOJ#2353 货币兑换
阅读量:6441 次
发布时间:2019-06-23

本文共 2770 字,大约阅读时间需要 9 分钟。

CDQ分治优化斜率优化DP。

有个结论就是每天买完卖完....知道这个之后考虑今天卖的是哪天买的就能写出n²DP了。

发现形式是fi = max(aibj + cidj)的形式。我们可以把ci除出来,就是斜率优化了。

然后发现横坐标和斜率全部没有单调性,于是CDQ分治搞一搞。

1 #include 
2 3 const int N = 1000010; 4 const long double eps = 1e-12; 5 6 long double a[N], b[N], c[N], R[N], f[N], s, k[N], v[N], w[N]; 7 int n, node[N], t[N], stk[N], top; 8 9 template
inline void Max(T &a, const T &b) {10 a < b ? a = b : 0;11 return;12 }13 14 inline bool cmp_k(const int &a, const int &b) {15 return k[a] < k[b];16 }17 18 inline bool cmp_w(const int &a, const int &b) {19 return w[a] < w[b];20 }21 22 inline bool check(int a, int b, int c) {23 if((v[b] - v[a]) * (w[c] - w[b]) + eps >= (v[c] - v[b]) * (w[b] - w[a])) {24 return 1;25 }26 return 0;27 }28 29 void CDQ(int l, int r) {30 31 //printf("CDQ : l = %d r = %d \n", l, r);32 33 if(l == r) {34 if(r > 1) f[r] *= b[r];35 Max(f[r], f[r - 1]);36 v[r] = -f[r] / c[r];37 w[r] = -v[r] * R[r];38 //std::cout << "v[i] = " << v[r] << std::endl;39 //printf("f = %.3f \n", f[r]);40 return;41 }42 int mid = (l + r) >> 1;43 CDQ(l, mid);44 45 /// update46 memcpy(t + l, node + l, (r - l + 1) * sizeof(int));47 std::sort(t + l, t + mid + 1, cmp_w);48 std::sort(t + mid + 1, t + r + 1, cmp_k);49 // build convex50 stk[top = 1] = t[l];51 if(mid - l + 1 >= 2){52 stk[++top] = t[l + 1];53 for(int i = l + 2; i <= mid; i++) {54 while(top > 1 && check(stk[top - 1], stk[top], t[i])) {55 top--;56 }57 stk[++top] = t[i];58 }59 }60 // update f61 //printf("top = %d \n", top);62 int head = 1;63 for(int i = mid + 1; i <= r; i++) {64 int x = t[i];65 while(head < top && (v[stk[head]] - v[stk[head + 1]]) / (w[stk[head]] - w[stk[head + 1]]) + eps < k[x]) {66 head++;67 }68 int y = stk[head];69 //printf("Max %.3f %.3f * %.3f \n", f[x], -v[y], (R[y] * a[x] + b[x]));70 //Max(f[x], -v[y] * (R[y] * a[x] + b[x]));71 Max(f[x], w[y] * k[x] - v[y]);72 }73 74 CDQ(mid + 1, r);75 return;76 }77 78 int main() {79 80 //freopen("in.in", "r", stdin);81 //freopen("my.out", "w", stdout);82 83 scanf("%d%Lf", &n, &s);84 for(int i = 1; i <= n; i++) {85 scanf("%Lf%Lf%Lf", &a[i], &b[i], &R[i]);86 c[i] = a[i] * R[i] + b[i];87 //std::cout << "c[i] = " << c[i] << std::endl;88 k[i] = a[i] / b[i];89 node[i] = i;90 }91 92 f[1] = s;93 94 CDQ(1, n);95 96 printf("%.3Lf\n", f[n]);97 return 0;98 }
AC代码

eps很重要...

 

转载于:https://www.cnblogs.com/huyufeifei/p/10547190.html

你可能感兴趣的文章
2018年中国银行业十件大事,“Fintech深度融合,科技子公司遍地” ...
查看>>
Git SSH 连接phacility服务器
查看>>
【客户案例】智能驾驶行业如何上云?
查看>>
foreman源NO_PUBKEY 6F8600B9563278F6
查看>>
揭秘:蚂蚁金服bPaaS究竟是什么?
查看>>
mongo数据库单节点搭建
查看>>
WPF模糊和阴影效果
查看>>
增加关系型数据库驱动配置同步任务
查看>>
别用这种方式聊天,你都不知道自己是怎么聊死的
查看>>
中国香港地区 DDoS- botnet 态势分析
查看>>
另一个角度的架构师
查看>>
SparseArray<E>详解
查看>>
Eclipse-Java代码规范和质量检查插件-PMD
查看>>
php实现上传图片保存到数据库的方法
查看>>
安卓应用安全指南 5.4.3 通过 HTTPS 的通信 高级话题
查看>>
针对CMS中的tag标签理解
查看>>
AR头显要上天!欧洲太空总署或用HoloLens维修太空站
查看>>
沃尔玛建立自家的人工智能网络,抗衡竞争对手亚马逊
查看>>
Mysql备份与还原及优化方法
查看>>
linux常用命令和选项
查看>>