洛谷P1868 饥饿的奶牛

题目链接

  我们要在这个区间中选出任意多个非重叠的区间,使得选出来的区间总长度最长。我们可以从最左端的位置开始枚举,一直枚举到最远的位置,我们用dp[i]来表示从1开始以i结尾的这一段没有重叠区间的最长长度。我们可以发现,只要我们枚举的点是在上一个点的后面,那么前面的最远距离其实是固定的,因为我们候选出来的点并不会对之前选出来的区间造成影响,也就是不具有后效性,我们可以考虑使用线性DP去求解这个问题。每一次的状态转移方程为: dp[i]=max(dp[i1],dp[j]+w[j,i])这个地方的w[j,i]表示的是从前一个j点选到i点的这一段合法的区间长度也就是ij

#include <bits/stdc++.h>

using i64 = long long;

#define rep(i, a, n) for (int i = a; i < n; i ++ )
#define per(i, a, n) for (int i = n - 1; i >= a; i -- )
#define SZ(a) (int(a.size()))
#define pb push_back
#define all(a) a.begin(), a.end()
//head

int n;
std::vector<int> br[3000010];
int dp[3000010];

int main() {
	scanf("%d", &n);

	int res = 0;
	rep(i,0,n) {
		int l, r;
		scanf("%d%d", &l, &r);
		br[r].pb(l - 1);
		res = std::max(res, r);
	}

	rep(i,1,res + 1) {
		dp[i] = dp[i - 1];
		for (int j = 0; j < SZ(br[i]); j ++ ) {
			int ver = br[i][j];
			dp[i] = std::max(dp[i], dp[ver] + i - ver);
		}
	}

	printf("%d\n", dp[res]);

	return 0;
}
posted @   浅渊  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示