种树问题-贪心算法

Description

某条街被划为 n 条路段,这 n 条路段依次编号为 1…n。每个路段最多可以种一棵树。现在居民们给出了 h 组建议,每组建议包含三个整数 b,e,t 表示居民希望在路段 b 到 e之间至少要种 t 棵树。这些建议所给路段的区间可以交叉。请问:如果要满足所有居民的建议,至少要种多少棵树。

 

Input

第一行为 n,表示路段数。第二行为 h,表示建议数。 下面 h 行描述一条建议:b,e,t 用一个空格分隔。

 

Output

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

 

Sample Input

9

4

1 4 2

4 6 2

8 9 2

3 5 2

 

 

Sample Output

5

 

 

 

思路

以样例为例,首先按右端点升序排序:

      

要使种的树数目最少,实际是要使树尽可能的种在路段重复地段。类似于安排时间表的问题,用贪心算法处理。排好序后按照路段顺序遍历,并且每次从最右端点向左遍历该路段,即从最右端开始种树。这样可以实现最大限度的把树优先种在重复路段。

以此思路则种树顺序应如图所示:

  

 

 

代码

#include<iostream>

#include<algorithm>

using namespace std;

struct node

{

       int b, e, t;

}sugg[5001];//suggestion

bool cmp(node x, node y){

    return x.e<y.e;//以右端点作为排序标准 升序

}

int main()

{

    int b,e,t;

       int n,h;

       cin>>n>>h;

       for(int i=1;i<=h;i++){

        cin>>sugg[i].b>>sugg[i].e>>sugg[i].t;

       }

       sort(sugg+1,sugg+1+h,cmp);

       int res=0;

       int road[10000]={0};//记录整个道路种树情况

       for(int i=1;i<=h;i++){

        //先循环遍历此路段是否满足建议需求

        for(int j=sugg[i].e;j>=sugg[i].b;j--){//从靠近右端点的地方开始种树

            if(road[j]==1){

                sugg[i].t--;

            }

        }

        //再循环从右端点开始种树

        for(int j=sugg[i].e;j>=sugg[i].b;j--){

            if(sugg[i].t==0){//此条建议已被满足

                break;

            }

            if(road[j]==1){//此处已有树

                sugg[i].t--;

            }else{

                sugg[i].t--;

                road[j]=1;//种上树

                res++;

            }

        }

       }

       cout<<res;

}

 

最佳种树距离算法在现实生活中有许多应用,如城市规划、电力网络规划等。在开发中,Java提供了一些算法和库来处理树结构和计算树的距离。以下是一种基于Java的最佳种树距离算法的示例: 首先,我们需要定义一个树的节点类,包含节点的值和指向其子节点的指针。在Java中可以通过一个类来实现: ```java class TreeNode { int value; TreeNode[] children; } ``` 接下来,我们可以实现一个函数来计算两棵树之间的距离。该函数将比较两棵树的节点,递归地计算它们之间的孩子节点的距离,并返回最佳种树距离。以下是一个示例实现: ```java public int bestTreeDistance(TreeNode tree1, TreeNode tree2) { if (tree1 == null && tree2 == null) return 0; // 如果两棵树都为空,则它们之间的距离为0 if (tree1 == null || tree2 == null) return Integer.MAX_VALUE; // 如果其中一棵树为空,则距离为无穷大 // 计算根节点的距离 int distance = Math.abs(tree1.value - tree2.value); // 递归地计算孩子节点之间的距离 if (tree1.children != null && tree2.children != null) { for (int i = 0; i < tree1.children.length; i++) { for (int j = 0; j < tree2.children.length; j++) { distance = Math.min(distance, bestTreeDistance(tree1.children[i], tree2.children[j])); } } } return distance; } ``` 以上代码采用了递归的方式计算两棵树之间的最佳种树距离。在每一步中,我们比较两棵树的节点,计算它们之间的距离,并递归地计算它们的孩子节点之间的距离。通过不断更新距离的最小值,我们最终可以得到最佳种树距离。 需要注意的是,以上代码只是一种示例实现,实际应用中可能需要根据具体要求进行相应的修改和优化。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值