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

Posted lixiao189

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P1209 [USACO1.3]修理牛棚 Barn Repair相关的知识,希望对你有一定的参考价值。

思路:

首先我们有一些地方木板是必须要覆盖的,那就是有牛的牛棚,所以我们可以先用一个book数组,用book[i]=1标记牛棚i有牛,之后我们用

O(最后一个有牛的牛棚编号-第一个有牛的牛棚编号+1)的时间就可以扫一遍整个数组,统计出有牛的牛棚的个数。之后由于不耻的老板供应木板是有数量限制的,所以我们在这之后还要把一些没有木板的地方连接起来,知道剩下的木板数量符合条件为止。假设有这样的一个区间,这个区间中所有的木板盖着的牛棚都是有牛的,在所有的这样的区间以外的牛棚都是没有牛的,我们先统计出这样区间有几个,之后就可以得到我们需要合并多少的区间,这样之后在把没有牛的区间长度统计出来并把每个没牛的区间的长度放入一个数组中,之后对数组进行排序,之后选出需要的长度,加在答案上就可以了。

ps:其实这道题目的解法其实就是最小生成树的简化版本

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 1e4+5;

int m,s,c;
int start=99999999,end1=-99999999;
int arr[N];
int book[N];

int main(){
    scanf("%d%d%d",&m,&s,&c);
    int tx;
    for(int i=1;i<=c;i++){
        scanf("%d",&tx);
        start=min(start,tx);
        end1=max(end1,tx);
        book[tx]++;
    }
    int sum=0;
    for(int i=start;i<=end1;i++){
        if(book[i]==1){
            sum++; //联通木条总长度
        }
    }
    int cnt=0; //连续牛棚区间的数量
    for(int i=2;i<=end1;i++){
        if(book[i]!=book[i-1] && book[i]==0){
            cnt++;
        }
    }
    if(book[end1]==1) cnt++;
    int rest=cnt-m; //需要联通的区间的数量
    int t_sum=0,head=0;
    for(int i=start;i<=end1;i++){ //获取每个未联通的区间的长度并存入数组 arr
        if(book[i]==0){
            t_sum++;
        }
        if(book[i]!=book[i-1] && book[i]==1 && i!=start){
            arr[head++]=t_sum;
            t_sum=0;
        }
    }
    if(book[end1]==0) arr[head++]=t_sum;
    sort(arr,arr+head); //也许有 Bug
    for(int i=0;i<rest;i++){
        sum+=arr[i];
    }
    printf("%d
",sum);
    return 0;
}

以上是关于题解 P1209 [USACO1.3]修理牛棚 Barn Repair的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

洛谷 P1209 修理牛棚== Codevs 2079 修理牛棚

38 修理牛棚