JOISC2019E 两道料理(Two Dishes)

题意

有两种菜,第一种菜有 n 个步骤,有花费时长 tai,限制 lai,价值 wai;第二种菜有 m 个步骤,有花费时长 tbi,限制 lbi,价值 wbi

对于一种菜的步骤 i,他需要完成该菜的步骤 1i1 才能进行该步骤。而你需要规划做这两道菜的步骤(两道菜的步骤可以交替进行),对于第一道菜的每个步骤 i,若你在 lai 时刻时已经完成了步骤 i,那么你会获得 wai 的收益;第二道菜同理。你需要最大化做完这 n+m 个步骤后的收益和最大值。

n,m106,|wai|,|wbi|109

分析

fi,j 表示第一道菜做了 1i 步骤,第二道菜做了 1j 步骤的最大收益。转移显然。

一个显然的性质:如果要获得 wai 的贡献,那么第二道菜必须完成不超过 pai 个步骤。对于 wbi 同理,我们也有一个 pbi

扫描线 i,考虑用数据结构维护 f,j。考虑将 wai,wbi 的贡献在加入 a 时计算:

  • wai 的贡献,考虑先将 wai 加入 ans 中,当加入 ai 时,若已经选了 bpai+1 则有 wai 的贡献。
  • wbi 的贡献,考虑当加入 apbi+1 时,若已经选了 bi,则有 wbi 的贡献。

这样我们就相当于在加入 ai 时会对 f,j 的一段后缀加,加完后令 f,j 取前缀最大值。

考虑差分,那么后缀加就相当于单点加,前缀最大值相当于前缀和最大值。考虑用 map 维护差分,那么 f,j 的值就是下标 j 的点值和。

若加入了一个非负数,那么直接加显然没问题。否则,将加入的这个数与下标在其之后的差分值兑掉,直到其之后的所有差分值都被兑掉或者加入的数在某处被兑掉了。如果加入的值把其之后的差分值都兑掉了,那么最后就不加入 map。注意到若先负后正那么负数的贡献会被错误的少加入,所以要先正后负。由于差分值只会被加一次删一次,总复杂度 O(nlogn)

int n,m;
int ta[maxn],la[maxn],wa[maxn],sa[maxn];
int tb[maxn],lb[maxn],wb[maxn],sb[maxn];
vector<pii>v[maxn];
map<int,int>f;
int ans;
void ins(int x,int val){
	if(val>=0)return f[x]+=val,void();
	for(auto it=f.lower_bound(x);it!=f.end();it=f.erase(it)){
		int id=it->fi;
		if(it->se+val>=0){
			f[id]+=val;
			return;
		}else{
			val+=it->se;
		}
	}
}
inline void solve_the_problem(){
	n=rd(),m=rd();
	rep(i,1,n)ta[i]=rd(),la[i]=rd(),wa[i]=rd(),sa[i]=sa[i-1]+ta[i];
	rep(i,1,m)tb[i]=rd(),lb[i]=rd(),wb[i]=rd(),sb[i]=sb[i-1]+tb[i];
	rep(i,1,n)if(la[i]>=sa[i]){
		int ps=upper_bound(sb+1,sb+m+1,la[i]-sa[i])-sb;
		ans+=wa[i];
		if(ps<=m)v[i].emplace_back(mp(ps,-wa[i]));
	}
	rep(i,1,m)if(lb[i]>=sb[i]){
		int ps=upper_bound(sa+1,sa+n+1,lb[i]-sb[i])-sa;
		if(ps<=n){
			v[ps].emplace_back(mp(i,wb[i]));
		}else{
			ans+=wb[i];
		}
	}
	rep(i,1,n){
		sort(all(v[i]),[](pii x,pii y){return x.se>y.se;});
		for(pii _:v[i]){
			int x=_.fi,val=_.se;
			ins(x,val);
		}
	}
	for(auto i:f)ans+=i.se;
	write(ans);
}

作者:dcytrl

出处:https://www.cnblogs.com/dcytrl/p/18725904

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   dcytrl  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示