在古埃及,人們使用單位分數的和(形如1/a的, a是自然數)表示一切有理數。 如:2/3=1/2+1/6,但不允許2/3=1/3+1/3,因爲加數中有相同的。 對於一個分數a/b,表示方法有很多種,但是哪種最好呢? 首先,加數少的比加數多的好,其次,加數個數相同的,最小的分數越大越 好。 如: 19/45=1/3 + 1/12 + 1/180 19/45=1/3 + 1/15 + 1/45 19/45=1/3 + 1/18 + 1/30, 19/45=1/4 + 1/6 + 1/180 19/45=1/5 + 1/6 + 1/18. 最好的是最後一種,因爲1/18比1/180,1/45,1/30,1/180都大。 給出a,b(0<a<b<1000),編程計算最好的表達方式。
a b
若干個數,自小到大排列,依次是單位分數的分母。
19 45
5 6 18
#include<bits/stdc++.h>
using namespace std;
const int N = 5000 + 5;
typedef long long ll;
ll gcd( ll a, ll b ){ return b == 0 ? a : gcd( b, a%b ); }
void yue( ll &a, ll &b ){
ll t = gcd( a, b );
a /= t; b /= t;
}
ll a,b,ans[N],as[N]; int tot; bool flag=0;
void dfs( ll a, ll b, int step, int pre ){
yue( a, b );
if( step == 1 ){
if( a == 1 && b > pre ){
if( flag && b >= ans[1] ) return;
flag = 1; as[1] = b;
memcpy( ans, as, sizeof(as) );
}
return;
}
for( int i = pre, mx = ceil((double)b*step/a); i <= mx; i++ )
as[step] = i, dfs( a * i - b, b * i, step - 1, i );
}
int main(){
scanf("%lld%lld", &a, &b);
yue( a, b );
while( !flag ) dfs( a, b, ++tot, 1 );
for( int i = tot; i; i-- ) printf("%lld ", ans[i]);
return 0;
}