广告牌安放问题

题目描述

某公司的广告部门为了增加盈利,决定要沿着当地一家公园的道路铺设广告(这是一个很好的盈利措施,因为有很多人每天会沿着公园的道路慢跑锻炼身体)。他们已经在准备建造一些广告牌,要将这些广告牌树立在路上。那么现在问题来了:如何安排广告牌的位置,使之既要达到宣传效果,又要尽量节省广告牌的开支(广告牌的数量最少)?
首先带领大家认识一下公园的道路:这是一条笔直的道路,用整数坐标表示路的某个位置。我们假定每个坐标处可以且最多可以放置一块广告牌。每个来锻炼身体的人的路线是固定的,从一个坐标处移动到另一个坐标处。在慢跑锻炼的过程中,人们可以看到自己路线内的所有广告牌。
公司的领导层规定要达到如下的宣传效果:要求每个人都要在锻炼的过程中看到至少一定数量的广告牌。如果一个人的锻炼距离不够放置如此多的广告牌,那么就要求这段距离全部放上广告牌,以达到尽量好的效果。

输入

多组测试数据。
测试数据为(N+1)行:
第一行有两个用空格分隔的整数KN (1 <= K, N <= 1000) K表示每个锻炼者在路上要看到广告牌的最少数量,N是锻炼者的数量。
接下来的N行描述每个锻炼者的路径。每行有两个整数AiBi (其绝对值均小于10000),分别表示起点和终点。

输出

输出满足宣传要求的要放置的广告牌的最少数量。

输入样例

5 10
1 10
20 27
0 -3
15 15
8 2
7 30
-1 -10
27 20
2 9
14 21

输出样例

19

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1050

struct route
{
    int Begin;
    int End;
};

bool cmp(route x, route y)
{
    return x.End < y.End;
}

route a[MAXN];
int pos[20010];
int main()
{
    int k, n;
    while(~scanf("%d%d", &k, &n))
    {
        for(int i = 0; i < n; i++)
        {
            scanf("%d%d", &a[i].Begin, &a[i].End);
            if(a[i].Begin > a[i].End)
                swap(a[i].Begin, a[i].End);
        }
        sort(a, a+n, cmp);
        memset(pos, 0, sizeof(pos));
        int num, need, ans;
        ans = 0;
        for(int i = 0; i < n; i++)
        {
            num = 0, need = 0;
            int x = a[i].Begin;
            int y = a[i].End;
            for(int j = x; j <= y; j++)
            {
                if(pos[j+10000])
                    num++;
            }
            if(num < k)
            {
                if(num < y-x+1)
                {
                    for(int j = y; j >= x; j--)
                    {
                        if(!pos[j+10000])
                        {
                            pos[j+10000] = 1;
                            need++;
                        }
                        if((num+need >= k) || (num+need == y-x+1))
                            break;
                    }
                }
            }
            ans += need;
        }
        printf("%d\n", ans);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值