Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 算法:在砍伐树木时找到最小的浪费?_Algorithm_Data Structures - Fatal编程技术网

Algorithm 算法:在砍伐树木时找到最小的浪费?

Algorithm 算法:在砍伐树木时找到最小的浪费?,algorithm,data-structures,Algorithm,Data Structures,给你n棵树,它们的高度在一个数组中。 给你一个k单位的值,你需要收集多少木材。 你可以有一把你想要的任何高度的斧头,但是当你选择时,你只能使用一把斧头 告诉你应该使用的斧头的最佳高度,以及你将砍伐哪些树木,这样你就可以得到最小的浪费 如果你用一把X高的斧头砍一棵H高的树。 如果H>X,则得到H-X木材 其他0木材 我试着解决这个问题,但除了蛮力这一相当糟糕的复杂性之外,我无法思考 更新以下查询 :- 如果斧头高度为0,则不必有0损耗 假设树的高度是2,4,k是5。我希望这能让问题变得清楚 在上面

给你n棵树,它们的高度在一个数组中。 给你一个k单位的值,你需要收集多少木材。 你可以有一把你想要的任何高度的斧头,但是当你选择时,你只能使用一把斧头

告诉你应该使用的斧头的最佳高度,以及你将砍伐哪些树木,这样你就可以得到最小的浪费

如果你用一把X高的斧头砍一棵H高的树。 如果H>X,则得到H-X木材 其他0木材

我试着解决这个问题,但除了蛮力这一相当糟糕的复杂性之外,我无法思考

更新以下查询 :- 如果斧头高度为0,则不必有0损耗 假设树的高度是2,4,k是5。我希望这能让问题变得清楚

在上面的例子中,斧头的高度是0,我需要砍掉2棵树来获得5个单位的木材。 损耗将是1个单位,我们必须尽量减少,这是最低限度的


不需要其他参数,如力或其他任何参数,这是一个NP完全问题,可简化为为为给定斧头高度选择最佳树集的问题。这部分问题是NP难问题,最著名的算法具有指数复杂性。

[编辑12/9/2013:最后一句中的固定公式!]

总是可以选择斧头的高度,以便砍掉高于此高度的所有树木不会造成任何浪费

见此,只需按高度降序对树木排序,并考虑将斧头高度从最高树顶部逐渐向下移动。假设最高的树的高度为h。请注意,函数

f(x) = total amount of wood cut by using an axe of height h - x to
       chop all trees of at least this height

当x=0时从0开始,是x的递增分段线性函数,没有间断。每当x增加超过一棵或多棵树刚开始变得可斩波的点时,f(x)的变化率就会增加,但这不会导致问题。因此,对于任何所需的木材y,只要(概念上)将高度y的水平线与图形f(x)相交,并从该点向下放置一条垂直线到x轴,以找到其值。(实际上,在一个程序中,我实际上是这样做的,但这里有一个提示:考虑树在不断降低的高度,以找到一对相邻的x值x1,x2,使得在H-X1上的砍削产生的木材太少,而H-X2产生的太多。)

看起来像是SPOJ的EKO问题…

1) 把树的高度分类。 2) 减去a[i](较大高度)-a[j](较小高度树)乘以考虑到尚未砍伐的树木总数

有关如何工作的更多详细信息,请查看

    #define gu getchar();
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
    inline int scan()
    {
        int n=0;
        char ch=gu;
        while(ch<48){ch=gu;}
        while(ch>47){n=(n<<3)+(n<<1)+ch-'0';ch=gu;}
        return n;
    }
bool dec(ll i,ll j)
{
    return (i>j);
}
ll a[1000000]={0};
int main()
{
    int n,i;
    ll l,m;
    scanf("%d %lld",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%lld",a+i);
    sort(a,a+n,greater<ll>());
    //for(int i=0;i<n;i++)
      //  printf("%lld ",a[i]);
    ll k=a[0];
    for(i=1;i<n;i++)
    {
        //printf("*%lld ",m);
        if(a[i]==k)
            continue;
        if((m-((i)*(k-a[i])))<=0)
        {
            if((m-((i)*(k-a[i])))==0)
            {printf("%d\n",a[i]);break;}
            else
            {
                ll z=(ll)(m/(i+1));
                m=m-z*(i);
                if(m==0)
                {printf("%lld\n",k-z);break;}
                if(m-(i+1)<0)
                {printf("%lld\n",k-z-1);break;}
            }
            printf("%lld ",m);
        }
        m=m-((i)*(k-a[i]));
        k=a[i];
    }
    return 0;
}
#定义gu getchar();
#包括
使用名称空间std;
typedef long-long-ll;
内联int扫描()
{
int n=0;
char ch=gu;

while(ch47){n=(n)无法理解您的问题。如果斧头的高度为0,您不会浪费任何木材,对吗?您能举一些例子吗?没有(物理)斧头高度和树木高度之间的直接关系:在不考虑其他变量的情况下,无法确定可以砍伐多少棵树、所需的工作量等(例如,施加在斧头上的力、施加该力的点、与树木的接触点、树木在切割点的阻力等).为了正确计算,你必须引入大量的物理变量,或者为了简化计算,你必须引入大量的限制;但无论如何,还需要更多的信息。从对木材数量的解释来看,我认为“斧头高度”是要进行切割的离地高度。高度必须是整数值吗?在2/4的情况下,可以在0.5的高度切割,这将使你得到1.5+3.5=5,这正是你需要的。如果不必是整数值,这个问题很小。斧头高度必须是非负的吗?如果不是,你总是可以切割第一个一棵斧头高度为k-H1的树。事实上,我们可以选择哪些树被砍掉,这实际上是一条红鲱鱼;-)总是有可能找到一个斧头高度,这样砍掉所有高于这个高度的树就会产生0浪费——看我的答案。但是,我们可以选择斧头高度这一事实会使这种减少无效,不是吗?如果我们有一个能为我们解决砍树问题的神谕,我们就不能将其限制在特定的斧头高度,所以我不知道我们如何才能做到用它来解子集和的一个特定实例。@ErikP.Correct。这只意味着我们通常不能通过评估任意斧头位置的成本来工作。我已经对j_random_hacker的答案投了更高的票,我很失望地看到它是净零票,而且还没有被接受。你能简化一下你的语言吗?你说的是strat,当x=0,当一棵或多棵树变得可砍时增加x,但当x=0时,整个树是可砍的。我不知道如何绘制图形。对于x的每个值,图形中的垂直线上都有n个点。我们可以举个例子绘制一个图形吗?假设树的高度为7,5,4,3。所需的值可以是5。也可以是17。给出17在这里,我们必须砍伐整个森林。@j_random_hacker:Peter的评论建议斧头高度必须是整数。(顺便说一句,我不是向下的投票人。)@ErikP:我在Peter的评论中(或关于问题本身)实际上没有看到任何东西表明——你看到了什么?@Peter For trees 7,5,4,3关键斧头高度和木材数量是多少(7,0), (5,2), (4,4), (3, 7), (0,19)。如果目标是5,我们应该在3到4之间切割。在4处切割得到4个单位,所以我们还需要一个单位。我们每单位斧头高度得到3个单位的木材,所以我们应该将斧头从4处降低1/3个单位,然后在3.6666666处切割……以实现零损耗。@j_random_hacker只是Peter给出的例子:我们必须切割整个斧头的唯一原因t=7,5,4,3,如果期望的数量是17,我能想到的是,如果高度需要是一个整数。对于k=5的2,4森林也是一样。这和它变为