贪心算法训练——种树

Posted nikkinikita

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心算法训练——种树相关的知识,希望对你有一定的参考价值。

1. 问题描述

  一条街道的一边有几座房子,因为环保原因居民想要在路边种些树,路边的地区被分割成 n 块,并被编号为 1…n,每块大小为一个单位尺寸并最多可以种一棵树,每个居民想在门前种些树并指定了三个数 b,e,t 这三个数分别表示该居民想在 b 和 e 之间最少种 t 棵树,当然,b<=e,t<=e-b+1 ,允许居民想种树的子区域可以交叉。出于资金紧缺的原因,环保部门请你求出能满足所有居民的种树要求时所需树的最少数量

2.输入格式

  第一行为 n,表示区域的个数

  第二行为 h,表示房子的数目

  下面 h 行描述居民的需要:b,e,t (0 < b <= e <= 30000,t <= e-b+1)分别用空格分开

3. 输出格式

  输出一个数,为满足所有居民的要求,所需要种树的最少数量

4. 样例输入

  9

  4

  1 4 2

  4 6 2

  8 9 2  

  3 5 2

5, 样例输出

  5

6. 思路分析

  按区间的末尾进行排序,从头开始,将区间的末尾加入队列,判断它是否存在于下个区间,如果存在,继续判断下一个区间,如果不存在,取下一个区间的末尾,继续判断,得到可以存在于公共位置的区间个数,就是可以节约的树的数量

7. 代码

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

using namespace std;

void insertion_sort(int a[],int arr[],int len);

int main()
{
    ios::sync_with_stdio(false);
    int n,h,num = 0,sum = 0;
    int i = 0;
    cin>>n>>h;
    int start[h],end[h],tree[h];
    for(; i < h; i++)
        cin>>start[i]>>end[i]>>tree[i];
    insertion_sort(start,end,h);
    int mark = end[0];
    for(i = 0;i<h;i++)
    {
        sum += tree[i];
        if(mark >= start[i])
            num++;
        else
            mark = end[i];
    }
    cout<<sum - num;
    return 0;
}
void insertion_sort(int a[],int arr[],int len)
{
    for(int i=1; i<len; i++)
    {
        int key=arr[i];int j;
        for(j=i-1; j>=0 && key<arr[j]; j--)
        {
            arr[j+1]=arr[j];
            a[j+1] = a[j];
        }
        arr[j+1]=key;
    }
}

 

以上是关于贪心算法训练——种树的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2151 种树(可反悔贪心,链表)BZOJ千题计划就图一乐

种树(贪心)

洛谷堆+贪心P1484 种树

BZOJ_2151_种树_贪心+堆+链表

BZOJ 2151 2151: 种树 (贪心+堆)

贪心算法:划分字母区间