P1209 [USACO1.3] 修理牛棚 Barn Repair

# P1209 [USACO1.3] 修理牛棚 Barn Repair

## 题目描述

在一个月黑风高的暴风雨夜,Farmer John 的牛棚的屋顶、门被吹飞了 好在许多牛正在度假,所以牛棚没有住满。   

牛棚一个紧挨着另一个被排成一行,牛就住在里面过夜。有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。   

自门遗失以后,Farmer John 必须尽快在牛棚之前竖立起新的木板。他的新木材供应商将会供应他任何他想要的长度,但是吝啬的供应商只能提供有限数目的木板。 Farmer John 想将他购买的木板总长度减到最少。

给出 $m,s,c$,表示木板最大的数目、牛棚的总数、牛的总数;以及每头牛所在牛棚的编号,请算出拦住所有有牛的牛棚所需木板的最小总长度。

## 输入格式

一行三个整数 $m,s,c$,意义如题目描述。   
接下来 $c$ 行,每行包含一个整数,表示牛所占的牛棚的编号。

## 输出格式

输出一行一个整数,表示所需木板的最小总长度。

## 输入输出样例 #1

### 输入 #1

```
4 50 18




14
15 
16 
17 
21
25 
26 
27 
30 
31 
40 
41 
42 
43
```

### 输出 #1

```
25
```

## 说明/提示

【数据范围】  
对于 $100\%$ 的数据,$1\le m \le 50$,$1\le c \le s \le 200$。 

USACO Training Section 1.3

正解

先说题,就是我们需要求的是最少需要木板的长度来把所有的有牛的牛棚竖起木板,这道题是一道经典的模板题,我们可以先从第一个到最后一个模板的长度(也就是一个板子),当成答案,分成m个板子,我们只需要将这一个板子切m-1次就变成m块了,又因为求的是最短,所以我们每次都要找大的切,我们可以把每个相邻板子的差值从大到小排序,找m-1个就可以

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N = 210;

int m, s, c;
int pos[N];
int sub[N];
int ans;

bool cmp(int a, int b)
{
    return a > b;
}

int main()
{
    cin >> m >> s >> c;

    for (int i = 1; i <= c; i++) scanf("%d", &pos[i]);

    if (m >= c) {
        cout << c << endl;
        return 0;
    }

    sort(pos + 1, pos + 1 + c);
    ans = pos[c] - pos[1] + 1;

    for (int i = 2; i <= c; i++) {
        sub[i - 1] = pos[i] - pos[i - 1]-1;
    }

    sort(sub + 1, sub + 1 + c - 1,cmp);

    for (int i = m, j = 1; i > 1; i--, j++) {
        ans -= sub[j];
    }

    cout << ans << endl;


    return 0;
}
 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值