题面传送门

题意:

有 \(n\) 个展销会,每个展销会给出它的时间 \(t_i\),举办展销会的位置 \(l_i\),和参加这个展销会你能得到的收益 \(m_i\)。

你现在在位置 \(s\),你可以花 \(u\) 的代价从 \(i\) 走到 \(i-1\),或是花 \(d\) 的代价从 \(i\) 走到 \(i+1\)。

你只能先参加时间靠前的展销会,再参加时间靠后的展销会。

问从 \(s\) 出发并回到 \(s\) 能够获得的最大收益。

\(1 \leq n,t_i \leq 5 \times 10^5\),\(1 \leq l_i \leq 5 \times 10^5+1\),可能存在相同的 \(t_i\)。

这是一道 dp 题。

先考虑一个弱化版本的问题,假设没有 \(t_i\) 相同。

不难想到将这 \(n\) 个展销会按 \(t_i\) 从小到大排个序。

然后设 \(dp_i\) 表示参加前 \(i\) 个展销会,当前在第 \(i\) 个展销会的最大收益。

枚举上一个参加的展销会,于是我们就有 \(dp_i=\max\{dp_j-cost(j,i)\}+m_i\),其中 \(cost(j,i)\) 表示从第 \(j\) 个展销会所在的位置到达第 \(i\) 个展销会所在的位置的代价。

我们进一步对 \(cost(j,i)\) 进行展开,就有

\(dp_i=\max\{dp_j-(l_j-l_i)\times u\}+m_i\quad(l_j\geq l_i)\)

\(dp_i=\max\{dp_j-(l_i-l_j)\times d\}+m_i\quad(l_j\lt l_i)\)

拿第一个柿子举例,将 \(dp\) 柿子拆成与 \(i\) 有关的和与 \(j\) 有关的两部分,也就有

\(dp_j-(l_j-l_i)\times u=dp_j-l_j\times u+l_i\times u=(dp_j-l_j\times u)+l_i\times u\)

用树状数组维护 \(dp_j-l_j\times u\) 的最大值就可以在 \(\mathcal O(\log n)\) 的时间内求出 \(dp_i\)


但加上 \(t_i\) 可能相同的条件怎么办呢?

在举办时间相同的展销会当中,我们肯定是从左往右依次经过某些展销会,或是从右到左依次经过某些展销会,不走回头路。

于是我们可以把这 \(t_i\) 相同的展销会按 \(l_i\) 从小到大排个序。(显然这 \(t_i\) 相同的展销会的下标能够组成一个区间)

先求出从举办时间小于 \(t_i\) 的展销会到达 \(i\) 的最小代价 \(x_i\)。

然后设 \(dpl_i\) 表示以 \(i\) 结尾的一条从左至右的路径的最小代价。

\(dpr_i\) 表示以 \(i\) 结尾的一条从右至左的路径的最小代价。

以 \(dpl_i\) 为例,要么从从举办时间小于 \(t_i\) 的展销会到达展销会 \(i\),也就是 \(x_i\),要么从展销会 \(i-1\) 到底 \(i\),也就是 \(dp_{i-1}-(l_i-l_{i-1})\times d+m_i\),两者取一个 \(\max\) 即可。

最后 \(dp_i=\max(dpl_i,dpr_i)\)。

别忘了最后要回到位置 \(s\)。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=500000+5;
const int MAXD=500001+5;
void chkmin(ll &x,ll y){(x>y)?(x=y):0;}
void chkmax(ll &x,ll y){(x<y)?(x=y):0;}
int n,s;ll u,d;
struct fair{
int t;ll l,m;
friend bool operator <(fair x,fair y){
if(x.t!=y.t) return x.t<y.t;
return x.l<y.l;
}
} a[MAXN];
struct fenwick_tree{
ll t[MAXD];
fenwick_tree(){memset(t,128,sizeof(t));}
void add(int x,ll v){for(int i=x;i<MAXD;i+=(i&(-i))) chkmax(t[i],v);}
ll query(int x){ll ret=-1e18;for(int i=x;i;i-=(i&(-i))) chkmax(ret,t[i]);return ret;}
} t1,t2;
ll dp[MAXN],dpd[MAXN],dpu[MAXN];
int main(){
scanf("%d%lld%lld%d",&n,&u,&d,&s);
t1.add(s,s*d);t2.add(MAXD-s+1,-s*u);
for(int i=1;i<=n;i++) scanf("%d%lld%lld",&a[i].t,&a[i].l,&a[i].m);
sort(a+1,a+n+1);memset(dp,128,sizeof(dp));
int l=1,r=1;
while(l<=n){
r=l;while(r<=n&&a[r].t==a[l].t) r++;r--;
// printf("%d %d\n",l,r);
for(int i=l;i<=r;i++){
dp[i]=max(dp[i],t1.query(a[i].l)-a[i].l*d);
dp[i]=max(dp[i],t2.query(MAXD-a[i].l-1)+a[i].l*u);
dp[i]+=a[i].m;
dpd[i]=dpu[i]=dp[i];
}
for(int i=l+1;i<=r;i++) dpd[i]=max(dpd[i],dpd[i-1]-(a[i].l-a[i-1].l)*d+a[i].m);
for(int i=r-1;i>=l;i--) dpu[i]=max(dpu[i],dpu[i+1]-(a[i+1].l-a[i].l)*u+a[i].m);
for(int i=l;i<=r;i++) dp[i]=max(dpd[i],dpu[i]);
for(int i=l;i<=r;i++) t1.add(a[i].l,dp[i]+a[i].l*d);
for(int i=l;i<=r;i++) t2.add(MAXD-a[i].l,dp[i]-a[i].l*u);
l=r+1;
}
// for(int i=1;i<=n;i++) printf("%lld\n",dp[i]);
ll ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i]-((a[i].l>s)?(a[i].l-s)*u:(s-a[i].l)*d));
printf("%lld\n",ans);
return 0;
}
/*
dp[i]=max{dp[j]+l[j]*d-l[i]*d}(l[j]<=l[i])
dp[i]=max{dp[j]-l[j]*u+l[i]*u}(l[j]>l[i])
*/

洛谷 P5902 [IOI2009]salesman(dp)的更多相关文章

  1. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  2. NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp

    原文链接https://www.cnblogs.com/zhouzhendong/p/9261079.html 题目传送门 - 洛谷P3959 题目传送门 - Vijos P2032 题意 给定一个 ...

  3. 洛谷P1244 青蛙过河 DP/思路

    又是一道奇奇怪怪的DP(其实是思路题). 原文戳>>https://www.luogu.org/problem/show?pid=1244<< 这题的意思给的挺模糊,需要一定的 ...

  4. 洛谷P3928 Sequence2(dp,线段树)

    题目链接: 洛谷 题目大意在描述底下有.此处不赘述. 明显是个类似于LIS的dp. 令 $dp[i][j]$ 表示: $j=1$ 时表示已经处理了 $i$ 个数,上一个选的数来自序列 $A[0]$ 的 ...

  5. 洛谷P1140 相似基因 (DP)

    洛谷P1140 相似基因 题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. ...

  6. 洛谷P2224 [HNOI2001] 产品加工 [DP补完计划,背包]

    题目传送门 产品加工 题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时 ...

  7. 洛谷1417 烹调方案 dp 贪心

    洛谷 1417 dp 传送门 挺有趣的一道dp题目,看上去接近于0/1背包,但是考虑到取每个点时间不同会对最后结果产生影响,因此需要进行预处理 对于物品x和物品y,当时间为p时,先加x后加y的收益为 ...

  8. 洛谷1387 二维dp 不是特别简略的题解 智商题

    洛谷1387 dp题目,刚开始写的时候使用了前缀和加搜索,复杂度大概在O(n ^ 3)级别,感觉这么写还是比较对得起普及/提高-的难度的..后来看了题解区各位大神的题解,开始一脸mb,之后备受启发. ...

  9. 洛谷 P2657 (数位DP)

    ### 洛谷 P2657 题目链接 ### 题目大意:给你一个数的范围 [A,B] ,问你这段区间内,有几个数满足如下条件: 1.两个相邻数位上的数的差值至少为 2 . 2.不包含前导零. 很简单的数 ...

随机推荐

  1. 微信h5跳转小程序wx-open-launch-weapp开放标签不显示(已解决)

    前言: 前几天成功对接了跳转第三方小程序的功能,今天有个页面有需要对接.但是奇怪的是用的和上次一模一样的配置,但就是死活不显示wx-open-launch-weapp这个开放标签的按钮,看不到任何效果 ...

  2. Java:ConcurrentHashMap类小记-3(JDK8)

    Java:ConcurrentHashMap类小记-3(JDK8) 结构说明 // 所有数据都存在table中, 只有当第一次插入时才会被加载,扩容时总是以2的倍数进行 transient volat ...

  3. BUAA-OO-最后单元总结

    BUAA-OO-最后单元总结 经过一学期的魔鬼"折磨"后,OO课程终于要结束了!总体来说我对于作业的总体完成情况还是比较满意的,希望最后可以取得一个理想成绩. 一.第四单元架构设计 ...

  4. Spring Cloud Alibaba 的服务注册与发现

    Spring Cloud Alibaba 服务发现例子 一.需求 1.提供者完成的功能 2.消费者完成的功能 3.可以附加的额外配置 二.实现步骤 1.总的依赖引入 2.服务提供者和发现者,引入服务发 ...

  5. 【Azure Redis 缓存】Windows版创建 Redis Cluster 实验 (精简版)

    简介 学习Redis Cluster的第一步,即本地搭建Redis Cluster.但是在Redis的官方文档中,是介绍在Linux系统中搭建Redis Cluster.本文主要介绍在Windows系 ...

  6. vim 让人爱不释手的编辑器之神

    VIM 基本介绍 vim诞生已有20多年,它常被人称之为编辑器之神,vim的操作理念可以说是独具一格而又出类拔萃,使用vim能极大的提升文本处理效率,因此熟练掌握vim应该是每个程序员都应该做到的事情 ...

  7. Veritas Backup Exec™ 21.3 Multilingual (Windows)

    Backup Exec 21.3, Release date: 2021-09-06 请访问原文链接:https://sysin.org/blog/veritas-backup-exec-21-3/, ...

  8. ubuntn 一直循环登录界面 (卸载nvidia驱动)

    由于在Ubuntu下安装了Nvidia显卡驱动后开机一直处于循环登录界面,密码输入正确也是进不去,然后就决定卸载Nvidia显卡驱动.首先是在能使用tty1登录的情况下,使用 $ sudo apt-g ...

  9. hdu 1069 Monkey and Banana(记忆搜)

    题意: N(不超过30)种木块,每种木块有长.宽.高x,y,z. 木块A可以搭在木块B上当且仅当A的底面长和宽都分别小于B的顶面的长与宽,即不能有超出B的部分. 问垒起来的"木块塔" ...

  10. OpenAPITools 实践

    OpenAPITools 可以依据 REST API 描述文件,自动生成服务端桩(Stub)代码.客户端 SDK 代码,及文档等.其是社区版的 Swagger ,差异可见:OpenAPI Genera ...