楼上的写的好,我的算法由于超过double的精度,导致在20处开始出现误差.
改正如下:
int getplanessimp(double& range/*飞行距离圈数*/,int m/*一箱油飞行圈数*/)//简单飞行
{
// 1/m+1/2m+...+1/nm >= range
double d = 0.0;//m*飞行距离
int n = 0;//飞机数
double t = range*m;
while(d < t && n >= 0)
{
n++;
d += 1.0/(n);//这里必须做浮点运算
}
range = d/m;//返回实际飞行距离
return n;
}
int getplanes(int m/*一箱油飞行圈数*/)
{
//从简单飞行记录看,为了多跑一个1/m距离,则需要增加的飞机比以前所有的飞机加起来还多
//所以每次都从基地接应返回的飞机,会节省很多。要实现能接回且飞机最好,则需要计算最远飞行距离为0.5+1.0/(2*m)圈
double d = 0.5+1.0/(2*m);//飞行半圈加上半箱油的距离
int n = 0;//飞机数
n = getplanessimp(d,m);
double r = 1.0 - d;//剩余距离
if(r <= 1.0/m)//返回不足一箱油距离,则从基地起飞的飞机需要飞行的距离为2r
{
r *= 2;
}
else//否则需要飞行的距离为返回距离加一箱油距离
{
r += 1.0/m;
}
while(r > 0.0)
{
double t = r;
n+=getplanessimp(t,m);//这里t为实际飞行距离,可以认为是从接回飞机处拿回接力棒,实际上可以把一架飞机的油全部给接回飞机
r -= 1.0/m + (t-r);//实际剩余距离
}
return n;
}
int need_plane(int m);
int main()
{
int m = 50; //一架飞机可以飞1/m圈地球
int n = need_plane(m);
printf("%d\n",n);
return 0;
}
//贪心算法:保证每架飞机浪费的最少,即只要其它飞机有空的就加满.
第一架飞机给了最后一架1/n的油
第二架飞机给了最后一架1/n-1的油
.....
倒数第二架给了最后一架1/2的油
int need_plane(int m)
{
double n = 1; //保存需要的飞机数
double sum_petro = 1.0;
while(sum_petro<m)
{
n++;
sum_petro += 1/n;
}
return n;
}
结果:
m = 1 ; n = 1
m = 2 ; n = 4
m = 3 ; n = 11
m = 4 ; n = 31
m = 5 ; n = 83
.
.
.
m = 20; n = 272400600
.
..