Codeforces Gym 101175F - Machine Works(CDQ 分治维护斜率优化)
首先很明显我们会按照 \(d_i\) 的顺序从小到大买这些机器,故不管三七二十一先将所有机器按 \(d_i\) 从小到大排序。
考虑 \(dp\),\(dp_i\) 表示在时刻 \(d_i\) 及以前卖掉手头的机器,最多能剩下多少钱。
转移显然就枚举上一个购买的机器编号 \(j\),即 \(dp_i=\max\limits_{j=1}^{i-1}dp_j-p_j+g_j(d_i-d_j-1)+r_j\),其中 \(j\) 可以转移到 \(i\) 当前仅当 \(dp_j\geq p_j\)。最终答案可以选择在某一时刻卖完某个机器后就不再买入新的机器了,即 \(\max\limits_{i=1}^ndp_i\),也可以选择将某个机器用到 \(D\) 天结束,即 \(\max\limits_{i=1}^ndp_i-p_i+g_i(D-d_i)+r_i(dp_i\ge p_i)\)
这样暴力转移是 \(n^2\) 的,但是有一个很明显的优化是这个 \(dp\) 转移满足斜率优化的 \(f_i=d_i+\max a_ib_j+c_j\) 的形式,故考虑斜率优化。考虑两个决策点 \(j,k\) 满足 \(g_j>g_k\),那么从 \(j\) 转移比从 \(k\) 转移更优当前仅当:
\]
斜率优化转移一下即可。
由于此题 \(g_i\) 不单调,故考虑 CDQ 分治维护斜率优化,具体来说,假设我们要用 \([l,mid]\) 中点的贡献更新 \(dp_{mid+1},dp_{mid+2},\dots,dp_r\),我们将 \([l,mid]\) 中所有满足要求的决策点按 \(g_i\) 从小到大排个序并依次加入凸壳,查找 \(d_i\) 的贡献时就在凸包上二分第一个斜率大于 \(-d_i\) 的点并转移即可。
还有就是对于 \(g_j=g_k\) 的 \(j,k\),相当于平面上坐标为 \(A(g_j,dp_j-p_j-g_j(d_j+1)+r_j),B(g_k,dp_k-p_k-g_k(d_k+1)+r_k)\) 的两点,那么我们对于横坐标相同的点肯定是先将纵坐标小的加入凸包,再将纵坐标大的加入凸包,因此在排序过程中要按\(g_j\) 为第一关键字,\(dp_j-p_j-g_j(d_j+1)+r_j\) 为第二关键字排序。我因此 WA 了好多好多发,xtbz。
这是萌新第二次写 CDQ 分治维护斜率优化哦,大佬不喜勿喷
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=1e5;
const ll INF=0x3f3f3f3f3f3f3f3fll;
int n,c,d,Casen=0;
struct event{
int d,p,r,g,id;
bool operator <(const event &rhs){
return d<rhs.d;
}
} a[MAXN+5],tmp[MAXN+5];
ll dp[MAXN+5];
int q[MAXN+5],tl=0;
double slope(int j,int k){
if(a[j].g==a[k].g) return INF;
return 1.0*((dp[j]-1ll*a[j].d*a[j].g-a[j].g+a[j].r-a[j].p)-(dp[k]-1ll*a[k].d*a[k].g-a[k].g+a[k].r-a[k].p))/(a[j].g-a[k].g);
}
int bsearch(int l,int r,int sl){
if(l==r) return l;int mid=l+r>>1;
if(slope(q[mid],q[mid+1])>sl) return bsearch(mid+1,r,sl);
else return bsearch(l,mid,sl);
}
void cdq(int l,int r){
if(l==r){chkmax(dp[l],dp[l-1]);return;}
int mid=l+r>>1;cdq(l,mid);for(int i=l;i<=mid;i++) tmp[i]=a[i];
sort(tmp+l,tmp+mid+1,[](event lhs,event rhs){
if(lhs.g^rhs.g) return lhs.g<rhs.g;int j=lhs.id,k=rhs.id;
return (dp[j]-1ll*a[j].d*a[j].g-a[j].g+a[j].r-a[j].p)<(dp[k]-1ll*a[k].d*a[k].g-a[k].g+a[k].r-a[k].p);
});
tl=0;
for(int i=l;i<=mid;i++){
if(dp[tmp[i].id]<tmp[i].p) continue;
while(tl&&slope(q[tl],tmp[i].id)>slope(q[tl-1],q[tl])) tl--;
q[++tl]=tmp[i].id;
}
for(int i=mid+1;i<=r;i++){
if(!tl) continue;
int pos=bsearch(1,tl,-a[i].d),id=q[pos];
chkmax(dp[i],dp[id]+1ll*(a[i].d-a[id].d-1)*a[id].g+a[id].r-a[id].p);
// printf("%d %d\n",i,id);
}
cdq(mid+1,r);
}
void solve(){
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&a[i].d,&a[i].p,&a[i].r,&a[i].g);
} sort(a+1,a+n+1);
for(int i=1;i<=n;i++) a[i].id=i;
memset(dp,0,sizeof(dp));
ll ans=c;dp[0]=c;cdq(1,n);
for(int i=1;i<=n;i++) if(dp[i]>=a[i].p)
chkmax(ans,dp[i]+a[i].r+1ll*(d-a[i].d)*a[i].g-a[i].p);
for(int i=1;i<=n;i++) chkmax(ans,dp[i]);
printf("Case %d: %lld\n",++Casen,ans);
}
int main(){
while(~scanf("%d%d%d",&n,&c,&d)){
if(!n||!c||!d) break;solve();
}
return 0;
}
Codeforces Gym 101175F - Machine Works(CDQ 分治维护斜率优化)的更多相关文章
- hdu 3842 Machine Works(cdq分治维护凸壳)
题目链接:hdu 3842 Machine Works 详细题解: HDU 3842 Machine Works cdq分治 斜率优化 细节比较多,好好体会一下. 在维护斜率的时候要考虑x1与x2是否 ...
- LOJ 2353 & 洛谷 P4027 [NOI2007]货币兑换(CDQ 分治维护斜率优化)
题目传送门 纪念一下第一道(?)自己 yy 出来的 NOI 题. 考虑 dp,\(dp[i]\) 表示到第 \(i\) 天最多有多少钱. 那么有 \(dp[i]=\max\{\max\limits_{ ...
- [NOI2007]货币兑换 cdq分治,斜率优化
[NOI2007]货币兑换 LG传送门 妥妥的\(n \log n\)cdq做法. 这题用cdq分治也可以\(n \log n\)但是在洛谷上竟然比一些优秀的splay跑得慢真是见了鬼了看来还是人丑常 ...
- [NOI2007]货币兑换 「CDQ分治实现斜率优化」
首先每次买卖一定是在某天 $k$ 以当时的最大收入买入,再到第 $i$ 天卖出,那么易得方程: $$f_i = \max \{\frac{A_iRate_kf_k}{A_kRate_k + B_k} ...
- BZOJ1492: [NOI2007]货币兑换Cash(CDQ分治,斜率优化动态规划)
Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...
- Codeforces 848C Goodbye Souvenir(CDQ 分治)
题面传送门 考虑记录每个点的前驱 \(pre_x\),显然答案为 \(\sum\limits_{i=l}^{r} i-pre_i (pre_i \geq l)\) 我们建立一个平面直角坐标系,\(x\ ...
- 【BZOJ4311】向量(线段树分治,斜率优化)
[BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...
- Codeforces 1093E Intersection of Permutations [CDQ分治]
洛谷 Codeforces 思路 一开始想到莫队+bitset,发现要T. 再想到分块+bitset,脑子一抽竟然直接开始写了,当然也T了. 最后发现这就是个裸的CDQ分治-- 发现\(a\)不变,可 ...
- HDU 3824/ BZOJ 3963 [WF2011]MachineWorks (斜率优化DP+CDQ分治维护凸包)
题面 BZOJ传送门(中文题面但是权限题) HDU传送门(英文题面) 分析 定义f[i]f[i]f[i]表示在iii时间(离散化之后)卖出手上的机器的最大收益.转移方程式比较好写f[i]=max{f[ ...
随机推荐
- Hadoop MapReduce 保姆级吐血宝典,学习与面试必读此文!
Hadoop 涉及的知识点如下图所示,本文将逐一讲解: 本文档参考了关于 Hadoop 的官网及其他众多资料整理而成,为了整洁的排版及舒适的阅读,对于模糊不清晰的图片及黑白图片进行重新绘制成了高清彩图 ...
- [no_code][Beta] 中期组内总结
$( "#cnblogs_post_body" ).catalog() 目前scrum meeting beta阶段目前共7次.在alpha阶段我们博客发布时间比较匆忙,是扣分项, ...
- CSS 奇技淫巧 | 巧妙实现文字二次加粗再加边框
本文将通过一个实际的业务需求,讲解如何实现 极端场景下文字加粗加边框效果 文字多重边框的效果 需求背景 - 文字的二次加粗 今天遇到这样一个有意思的问题: 在文字展示的时候,利用了 font-weig ...
- 【做题记录】CF1444A Division
CF1444A Division 题意: 给定 \(t\) 组询问,每组给两个数 \(p_i\) 和 \(q_i\) ,找出最大的整数 \(x_i\) ,要求 \(p_i\) 可被 \(x_i\) 整 ...
- 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(二)
一.基于邻接表的Dijkstra算法 如前一篇文章所述,在 Dijkstra 的算法中,维护了两组,一组包含已经包含在最短路径树中的顶点列表,另一组包含尚未包含的顶点.使用邻接表表示,可以使用 BFS ...
- HttpContext.Current.Request.Url 地址:获取域名
假设当前页完整地址是:http://www.test.com/aaa/bbb.aspx?id=5&name=kelli 协议名----http://域名 ---- www.test.com站 ...
- Connected to an idle instance.
Connected to an idle instance:连接到空闲实例 原因:数据库或者监听没启动
- Win10自动备份oracle数据库
1.环境 操作系统:win10 数据库: 2.创建backup.bat文件 [ @echo offset name=%date:~0,4%%date:~5,2%%date:~8,2%set backu ...
- 小入门 Django(做个疫情数据报告)
Django 是 Python web框架,发音 [ˈdʒæŋɡo] ,翻译成中文叫"姜狗". 为什么要学框架?其实我们自己完全可以用 Python 代码从0到1写一个web网站, ...
- 使用 SSL 加密的 JDBC 连接 SAP HANA 数据库
近期客户为满足安全要求,提了让业务应用使用 SSL 方式连接 SAP HANA 数据库的需求.本人查询 SAP官方文档 发现数据库支持 SSL 连接,有参数直接加到 JDBC 的 URL 后边就行了, ...