E. Linear Kingdom Races

https://codeforces.com/problemset/problem/115/E

线段树优化dp O(n2)->O(nlogn)

分析题意发现可以有暴力dp

dp(i)是前i条路最大利润

dp(i)=dp(i-1)不选第i条路

dp(i)=max(dp(j)+val(j)-cost(j))选这i条路

dp(i)=max(dp(i-1),max(dp(j)+val(j)-cost(j))

显然右边值可以用线段树优化,不需要枚举

思考枚举就是val(j)-cost(j)+dp(j) 因此我们可以直接维护这些值

枚举i

(0-i-1)减去(a(i))建立这条路需要的钱

枚举建立前i条路可以获利的

(0-l-1)加上

求区间max(0,i-1) 从(i-1)内转移到 i

给i赋值dp(i)

ans=dp(n)

cpp 复制代码
// Problem: E. Linear Kingdom Races
// Contest: Codeforces - Codeforces Beta Round 87 (Div. 1 Only)
// URL: https://codeforces.com/contest/115/problem/E
// Memory Limit: 256 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<vector>
#include<algorithm>
#define INF 1e6
using namespace std;
const int N=2e5+9;
typedef long long ll;
int a[N];
ll dp[N];
struct competition{
	int l;
	ll w;
};
vector<competition> race[N];
struct SEG{
	struct node{
		ll mx;
		ll tag;
	}seg[N<<2];
	#define tl(id) id<<1
	#define tr(id) id<<1|1
	#define pushup(id) seg[id].mx=max(seg[tl(id)].mx,seg[tr(id)].mx)
	int inrange(int L,int R,int l,int r){return L>=l && R<=r;}
	int outofrange(int L,int R,int l,int r){return L>r || l>R;}
	void maketag(int id,ll v){
		seg[id].mx+=v;
		seg[id].tag+=v;
	}
	void pushdown(int id){
		maketag(tl(id),seg[id].tag);
		maketag(tr(id),seg[id].tag);
		seg[id].tag=0;
	}
	void modify(int id,int L,int R,int l,int r,ll v){
		if(inrange(L,R,l,r)){
			maketag(id,v);
		}else if(!outofrange(L,R,l,r)){
			int mid=(L+R)>>1;
			pushdown(id);
			modify(tl(id),L,mid,l,r,v);
			modify(tr(id),mid+1,R,l,r,v);
			pushup(id);
		}
	}
	ll query(int id,int L,int R,int l,int r){
		if(inrange(L,R,l,r)){
			return seg[id].mx;
		}else if(!outofrange(L,R,l,r)){
			int mid=(L+R)>>1;
			return max(query(tl(id),L,mid,l,r),query(tr(id),mid+1,R,l,r));
		}else{
			return 0;
		}
	}
}t;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=m;i++){
		int l,r,w;
		cin>>l>>r>>w;
		race[r].push_back((competition){l,w});
	}
	for(int i=1;i<=n;i++){
		t.modify(1,0,n,0,i-1,-a[i]);
		for(int j=0;j<race[i].size();j++){
			competition tt =race[i][j];
			t.modify(1,0,n,0,tt.l-1,tt.w);
		}
		dp[i]=max(dp[i-1],t.query(1,0,n,0,i-1));
		t.modify(1,0,n,i,i,dp[i]);
	}
	cout<<dp[n]<<'\n';
	return 0;
}
相关推荐
HW-BASE1 小时前
《C语言》指针练习题--1
c语言·开发语言·单片机·算法·c
泽虞2 小时前
数据结构与算法
c语言·数据结构·算法
max5006003 小时前
深度学习的视觉惯性里程计(VIO)算法优化实践
人工智能·深度学习·算法
岁忧3 小时前
(nice!!!)(LeetCode 每日一题) 3363. 最多可收集的水果数目 (深度优先搜索dfs)
java·c++·算法·leetcode·go·深度优先
shenghaide_jiahu4 小时前
数学建模——粒子群算法
算法·数学建模
无规则ai5 小时前
动手学深度学习(pytorch版):第一章节——引言
人工智能·pytorch·深度学习·算法·机器学习
WeiJingYu.5 小时前
机器学习——随机森林
算法·随机森林·机器学习
丶小鱼丶6 小时前
二叉树算法之【中序遍历】
java·算法
快去睡觉~8 小时前
力扣238:除自身之外数组的乘积
数据结构·算法·leetcode
Aczone288 小时前
数据结构(五):顺序循环队列与哈希表
数据结构·哈希算法·散列表