UVa 10148 - Advertisement

  题目大意:有一些广告牌,为了使跑步者看到固定数量的广告,设计所需租用的最少数量的广告牌。

  其实就是区间选点问题:数轴上有n个区间[ai, bi],取尽量少的点,使得每一个区间都至少有一个点。首先对区间进行排序(按b从小到大的顺序,若b相同则按a从大到小的顺序),然后做出贪心选择:选取第一区间最后一个位置的点,然后逐个区间判断,若已经有点则无需处理,没有点的话选择该区间最后位置的点。本题则是变为k个点,道理是相同的,从后往前进行选点就可以了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 #define MAXN 1000+10
 6 
 7 struct Interval
 8 {
 9     int l, r;
10     bool operator < (const Interval& x) const
11     {
12         if (r != x.r)   return r < x.r;
13         else return l > x.l;
14     }
15 };
16 Interval interval[MAXN];
17 bool payed[20000+100];
18 
19 int main()
20 {
21 #ifdef LOCAL
22     freopen("in", "r", stdin);
23 #endif
24     int T;
25     scanf("%d", &T);
26     while (T--)
27     {
28         int k, n;
29         scanf("%d%d", &k, &n);
30         for (int i = 0; i < n; i++)
31         {
32             int x, y;
33             scanf("%d%d", &x, &y);
34             interval[i].l = min(x, y);
35             interval[i].r = max(x, y);
36         }
37         sort(interval, interval+n);
38         memset(payed, 0, sizeof(payed));
39         int ans = 0;
40         for (int i = 0; i < n; i++)
41         {
42             int len = interval[i].r - interval[i].l + 1;
43             if (len < k)
44             {
45                 for (int j = interval[i].l; j <= interval[i].r; j++)
46                     if (payed[10000+j] == false)
47                     {
48                         payed[10000+j] = true;
49                         ans++;
50                     }
51             }
52             else
53             {
54                 int cnt = 0;
55                 for (int j = interval[i].l; j <= interval[i].r; j++)
56                     if (payed[10000+j])   cnt++;
57                 if (cnt < k)
58                 {
59                     int remain = k - cnt;
60                     int p = interval[i].r;
61                     while (p >= interval[i].l && remain > 0)
62                     {
63                         if (payed[10000+p] == false)
64                         {
65                             payed[10000+p] = true;
66                             ans++;
67                             remain --;
68                         }
69                         p--;
70                     }
71                 }
72             }
73         }
74         printf("%d\n", ans);
75         for (int i = 0; i < 20005; i++)
76             if (payed[i])   printf("%d\n", i-10000);
77         if (T)   printf("\n");
78     }
79     return 0;
80 }
View Code

 

posted @ 2013-08-17 21:27  xiaobaibuhei  阅读(314)  评论(0编辑  收藏  举报