您将获得n个树高度为数组的树。 并且你得到一个价值k单位,你需要收集多少木材。 你可以拥有自己想要的任何高度的斧头,但是当你选择时你只能使用1把斧头。
告诉你应该使用的最佳斧头高度,以及你要砍伐的树木,以便减少浪费。
如果你用高度为X的斧头切割一棵高度为H的树。 如果H> X,则得到H-X木材 别的0木头
我尝试了这个问题,但是我无法想到蛮力,这是非常糟糕的复杂性。
更新以下查询 : - 如果斧头高度为0,则无需浪费0 说树的高度是2,4,k是5.我希望这可以使查询清晰。
在上述情况下,ax的高度为0,我需要切割2棵树以获得5单位的木材。 浪费将是1个单位,我们必须尽量减少,这是最小的
不需要像force或其他任何其他参数
答案 0 :(得分:0)
Subset sum可以简化为给定斧头高度选择最佳树木组的问题。你问题的那部分是NP难的,而最着名的算法具有指数复杂性。
答案 1 :(得分:0)
[编辑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
当p = 0时,从0开始,并且是x的分段线性函数的增加,没有不连续性。每当x增加超过一棵或多棵树刚开始变得可砍伐的点时,f(x)的变化率就会增加,但这不会引起问题。因此,对于任何期望的木材y水平,仅(概念上)将高度y的水平线与图形f(x)相交,并且从该点向下垂直到x轴以找到其值。 (如何在我作为练习留下的程序中实际执行此操作,但这里有一个提示:考虑降低高度的树木顺序以找到一对相邻的x值x1,x2使得在h - x1处切割产生的木材太少,并且h - x2产生太多。)
答案 2 :(得分:0)
看起来像是蠢事的问题......
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;
}