1 条题解
-
0
题目分析
我们需要从给定的 个区间 中,每个区间至少选择 个数,构造一个新的集合 。求在满足所有约束条件下, 至少包含多少个数。
解题思路
-
变量定义:
- 设 表示从 到 中被选出的数的个数。
- 目标是求 (即整个范围内至少选多少个数)。
-
约束条件:
- 非递减约束:,即从 到 选的数不会比 到 选的数少。 [ S_i \geq S_{i-1} ]
- 相邻差约束:,即相邻位置最多选 个数。 [ S_{i-1} \geq S_i - 1 ]
- 区间约束:对于每个区间 ,至少选 个数。 [ S_{b_i} \geq S_{a_i - 1} + c_i ]
-
图的构建:
- 将不等式转化为图的边:
- :从 向 连一条权值为 的边。
- :从 向 连一条权值为 的边。
- :从 向 连一条权值为 的边。
- 由于 和 可能从 开始,我们统一将其 ,避免与源点 冲突。
- 将不等式转化为图的边:
-
最长路求解:
- 由于约束条件是 ,我们需要求最长路。
- 从源点 出发,计算到 的最长路, 即为答案。
关键点
- 源点的可达性:
- 由于约束 保证了从 出发可以遍历所有点,因此源点 能到达所有边。
- 边界处理:
- 将输入区间 的 和 都 ,避免 下标问题。
复杂度分析
- 时间复杂度:
- 最长路计算(如 SPFA)的最坏情况为 ,其中 是点数, 是边数。
- 空间复杂度:
- 存储图的边和距离数组,空间复杂度为 。
#include <iostream> #include <cstring> using namespace std; const int N = 50010, M = 150010; int n; int h[N],w[M],e[M],ne[M],idx; int dist[N]; int q[N]; bool st[N]; void add(int a,int b,int c){ e[idx] = b; w[idx] = c; ne[idx] = h[a]; h[a] = idx++; } void spfa(){ memset(dist,-0x3f,sizeof dist); int hh = 0, tt = 1; dist[0] = 0; q[0] = 0; st[0] = true; while(hh != tt){ int t = q[hh++]; if(hh == N) hh = 0; st[t] = false; for(int i = h[t]; ~i; i = ne[i]){ int j = e[i]; if(dist[j] < dist[t] + w[i]){ dist[j] = dist[t] + w[i]; if(!st[j]){ q[tt++] = j; if(tt == N) tt = 0; st[j] = true; } } } } } int main(int argc, char** argv) { scanf("%d",&n); memset(h,-1,sizeof h); for(int i = 1; i <= 50001; i++){ add(i-1,i,0); add(i,i-1,-1); } for(int i = 0; i < n; i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); a++; b++; add(a-1,b,c); } spfa(); printf("%d",dist[50001]); return 0; }
-
- 1
信息
- ID
- 202
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者