#10022. 「一本通 1.3 练习 1」埃及分数
【题目描述】
在古埃及,人们使用单位分数的和(形如 $\dfrac{1}{a}$ 的,$a$ 是自然数)表示一切有理数。如:$\dfrac{2}{3} = \dfrac{1}{2} + \dfrac{1}{6}$,但不允许 $\dfrac{2}{3} = \dfrac{1}{3} + \dfrac{1}{3}$,因为加数中有相同的。对于一个分数 $\dfrac{a}{b}$,表示方法有很多种,但是哪种最好呢?首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。
【算法】
$IDA^*$
【代码】
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a,b,dep;
ll ans[110],tmp[110];
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;
}
bool dfs(int now,ll y,ll aa,ll bb) {if(now==dep) {if(bb%aa) return 0;tmp[dep]=bb/aa;if(!ans[dep]||tmp[dep]<ans[dep]) memcpy(ans,tmp,sizeof(tmp));return 1;}int flag=0;for(ll i=max(bb/aa,y);;i++) {if(bb*(dep-now+1)<=aa*i) break;if(bb>aa*i) continue;tmp[now]=i;ll a2=aa*i-bb; ll b2=bb*i;ll g=gcd(a2,b2);if(dfs(now+1,i+1,a2/g,b2/g)) flag=1;}return flag;
}
int main() {scanf("%d%d",&a,&b);for(dep=2;;dep++) {if(dfs(1,b/a,a,b)) break;}for(int i=1;i<=dep;i++) printf("%I64d ",ans[i]); puts("");return 0;
}