数轴上有n个闭区间 [ a i , b i ] [a_i,b_i] [ai,bi]。选择尽量少的点,使得每个区间内都至少有一个选择的点。
算法:
将区间按右端点从小到大排序,依次枚举每个区间。
如果区间包含点:跳过
如果区间不包含点:将点放在区间右端点。
正确性:
设算法得到的点的个数是A,最优解得到点的个数是B
A
≥
B
A \geq B
A≥B:
因为每个区间都包含点,因此A是合法解,最优解显然不超过合法解。
B
≥
A
B \geq A
B≥A:
按照算法选出来的放点的区间,一定是两两没有交集的,否则这个区间会包含上个区间放的点。
因为这些区间两两没有交集,这些区间数为A,因为每个点至多覆盖1个这种区间,所以至少要放A个点。
因此所有可行方案的解 ≥ A \geq A ≥A,最优解也是可行方案,即最优解 B ≥ A B\geq A B≥A。
UVA10148
题目链接
某条街道上有很多个广告位,某公司在这条街上投放广告,1位置只能投放1个广告。因为不同地方的人流量是不同的,所以公司先调查了N个人,知道了他们每个人每天在街上走的路段。
现在要求找到一些广告位,使得广告位总数量最少,但是要求调查到的那些每人至少看到K次广告。如果有人走的路段广告位少于K个,那么要求他路段上的所有广告位都要有广告。输出要求的广告位的位置。
输入:
第一行输入K和N,
(
1
≤
K
,
N
≤
1000
)
(1 \leq K, N \leq 1000)
(1≤K,N≤1000)
接下去N行输入区间左端点l和右端点r,
(
−
10000
≤
l
,
r
≤
10000
)
(-10000\leq l, r \leq 10000)
(−10000≤l,r≤10000)
输出:
整数M,代表最少的广告数
接下去M行,代表广告的坐标
做法:
先按右端点从小到大排序,再按左端点从大到小排序,这样相同右端点更长的区间会在前面。
依次遍历每个区间,查看区间长度
1、区间长度<=K,从区间左端点遍历到右端点,每个点插上广告,之前已经被插过广告的点跳过。
2、区间长度>K,从区间左端点遍历到右端点计算广告总数,如果大于K则跳过,否则从区间右端点往左端点插广告插到=K为止。
情况1其实可以包括在情况2里,只要改下判断:往左端点插广告插到=K并且不超过左端点。
因为区间范围较小,所以这样做时间复杂度是2e7,可以接受。
注意两个test之间要有回车隔开,多一个少一个都不行。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int T, K, N, M, ans;
bool flag[20005];
struct Node {
int l, r;
bool operator< (Node p) //自定义比较函数
{
//按照right从小到大排序,right相等按left从大到小排序
if(r != p.r) return r < p.r;
else return l > p.l;
}
};
Node p[1005];
int main() {
scanf("%d", &T);
while (T -- ) {
scanf("%d%d", &K, &N);
for (int i = 0; i < N; i ++ ) {
scanf("%d%d", &p[i].l, &p[i].r);
if (p[i].l > p[i].r) swap(p[i].l, p[i].r);
}
sort(p, p + N);
memset(flag, 0, sizeof flag);
ans = 0;
for (int i = 0; i < N; i ++ ) {
int l = p[i].l + 10000, r = p[i].r + 10000;
int cnt = 0;
for (int j = l; j <= r; j ++ ) {
if (flag[j]) cnt ++ ;
}
if (cnt < K) {
int cnt2 = 0;
for (int j = r; j >= l && cnt + cnt2 < K; j -- ) {
if (!flag[j]) {
ans ++ ;
cnt2 ++ ;
flag[j] = true;
}
}
}
}
printf("%d\n", ans);
for (int i = 0; i <= 20000; i ++ ) {
if (flag[i]) printf("%d\n", i - 10000);
}
if (T) printf("\n");
}
return 0;
}
该博客探讨了一个算法问题,涉及在数轴上选择最少的点以确保每个闭区间内至少有一个点。通过排序区间并按特定规则插入点,可以找到最优解。问题的应用场景是广告投放,要求在街道的广告位上放置最少数量的广告,确保每个行人至少看到指定次数的广告。算法首先按右端点排序,然后遍历区间,根据区间长度决定插入广告的位置。此方法在时间复杂度上是可行的。
514

被折叠的 条评论
为什么被折叠?



