[题解]CF1175E Minimal Segment Cover
思路
这是一道简单的 DP 题,DP 题的核心就是状态转移。
先来说一说 数组的含义。
表示从 这个点用 条线段能走到的最远的点。
我们再来考虑一下边界情况。
因为我们只用 条线段,那么:
接着,我们递推一遍,从前往后更新一遍最大值。
即:
然后我们对 数组进行递增。
即:
注:以上递推和递增的操作都需要从 到 ,原因是:我们操作都是预处理,最后直接求答案的。
最后,我们直接用一个循环来求出答案。
如果 ,那么我们的结果直接加上 ,将 更新为 。
结果要加上 的原因是:我们从 数组的含义出发,我们需要的线段数量便是
将 更新成 的原因是:我们把点 之前的所有点都走过了,所以我们直接更新即可
我们最后算出来的结果是终点的上一个点,所以我们需要判断一下最后一个是否有解就行了,如果有解输出结果 + 1,否则输出 -1
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n,m;
int dp[N + 100000/*要开大一点,不然越界*/][25];
int main(){
cin >> n >> m;
for (int i = 1;i <= n;i++){
int a,b;
cin >> a >> b;
dp[a][0] = max(dp[a][0],b);
}
for (int i = 1;i <= N;i++) dp[i][0] = max(dp[i][0],dp[i - 1][0]);
for (int i = 1;i <= 19;i++){
for (int j = 0;j <= N;j++){
dp[j][i] = dp[dp[j][i - 1]][i - 1];
}
}
while (m--){
int x,y;
int res = 0;
cin >> x >> y;
for (int i = 19;i >= 0;i--){
if (dp[x][i] < y){
res += (1 << i);
x = dp[x][i];
}
}
if (dp[x][0] >= y) cout << res + 1 << endl;
else puts("-1");
}
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18264792
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】