• UVa 10148


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

      其实就是区间选点问题:数轴上有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
    ", ans);
    75         for (int i = 0; i < 20005; i++)
    76             if (payed[i])   printf("%d
    ", i-10000);
    77         if (T)   printf("
    ");
    78     }
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    【Nginx】url 带有 “https://” 双斜杠特殊处理
    【layui】tepmlet 格式化 table 数据
    于二零二零年:终章
    【Golang】练习-Web 处理 form 表单请求失败不刷新页面并保存输入的数据
    实现纸牌游戏的随机抽牌洗牌过程(item系列几个内置方法的实例)
    面向对象的进阶(item系列,__new__,__hash__,__eq__)
    面向对象阶段复习
    计算器实例
    反射
    静态方法staticmethod和类方法classmethod
  • 原文地址:https://www.cnblogs.com/xiaobaibuhei/p/3265150.html
Copyright © 2020-2023  润新知