修理牛棚问题

东华OJ49题 修理牛棚

题目如下

在一个暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假, 所以牛棚(牛棚的总数S:1<= S<=200)没有住满。 剩下的牛一个紧挨着另一个被排成一行安置在有 屋顶的牛棚来过夜。 所以有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度,且宽度设为1。 因为有些门遗失,农民约翰需要架起新的木板作为门。 他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板。 农民约翰想将他购买的木板总长度减到最少。 计算拦住所有有牛的牛棚所需木板的最小总长度。 输出所需木板的最小总长度作为的答案。 说明:拦住一个牛棚需要的木板长度为1,拦住相邻的三个牛棚则需要木板长度为3比如有牛的牛棚编号为:3 5 8 10 11 并且只能使用两块木板, 则第一块木板从35,长度为3第二块木板从811,长度为4因此,需要木板的总长度为7 输入说明 : 1: MC(用空格分开) 2C+1: 每行包含一个整数,表示牛所占的牛棚的编号。 其中:可能买到的木板最大的数目:M(1<= M<=50); 需要安置的牛的数目C(1<= C <=S) 安置后牛所在的牛棚的编号stall_number(1<= stall_number <= S)

解题思路

这道题乍一看其实会有点懵,不知如何下手,因为这涉及到了如何分组的问题。直接对牛棚编号序列进行分组没啥头绪,但是按照常理就是把离得近的一群分为一个组,按照这样的想法延申出一种解题思路:

  • 我们先将相邻两个牛棚的距离算出来,保存到一个数组或者向量中
  • 然后因为要分出M组,那其实就相当于切了M-1刀,那该怎么切呢?
    • 按照常理切呗,离得远的切
    • 所以找到距离数组中最大的M-1个距离切

这样切完就找到了M个分组,大体思路就是这样。

当然我们还需要注意一些小细节:

  • 当只有一块木板时,直接用最大的牛棚编号 -最小的牛棚编号即可
  • 当木板数>=牛棚个数时,最小距离就是牛棚个数
  • 输入的时候牛棚编号未必有序,所以需要排序

代码实现

实现时的一些小技巧:在距离数组中,在哪切一刀,就把那个值变成1,最后将距离数组中的值全部相加,最后加1即是结果。

#include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { int M, C, x; vector<int> cows; vector<int> dist; cin >> M >> C; if (M >= C) { cout << C; return 0; } while (C--) { cin >> x; cows.push_back(x); } sort(cows.begin(), cows.end()); if (M == 1){ cout << cows.back() - cows.front() + 1 << endl; return 0; } for (int i = 1; i< cows.size(); i++) dist.push_back(cows[i] - cows[i-1]); int idx = 0; while (--M) { for (int i = 0; i < dist.size(); i++) if (dist[i] > dist[idx]) idx = i; dist[idx] = 1; } int sum = 0; for (auto i : dist) sum += i; sum++; cout << sum; return 0; }

__EOF__

本文作者Fortunater
本文链接https://www.cnblogs.com/Fortunater/p/16034792.html
关于博主:不急不躁,一步一步走向技术巅峰
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   凡璞  阅读(47)  评论(0编辑  收藏  举报
1 2
3 4
5 6
点击右上角即可分享
微信分享提示