埃及分数 迭代加深搜索 IDA*
迭代加深搜索 IDA*
首先枚举当前选择的分数个数上限maxd,进行迭代加深
之后进行估价,假设当前分数之和为a,目标分数为b,当前考虑分数为1/c,那么如果1/c×(maxd - d)< a - b那么不可能得解,进行剪枝
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 6 const int maxn = 100; 7 const int inf = 2139062143; 8 int a, b; 9 int ans[maxn], cur[maxn]; 10 int maxd = 0; 11 12 13 bool better(void) { 14 for (int i = maxd; i >= 1; i--) { 15 if (cur[i] < ans[i]) return (1); 16 else if (cur[i] > ans[i]) return (0); 17 } 18 } 19 20 int gcd(int x, int y) { 21 return (y == 0 ? x : gcd(y, x % y)); 22 } 23 24 int getfirst(int aa, int bb) { 25 if (bb % aa == 0) return (bb / aa); 26 else return (bb / aa + 1); 27 } 28 29 void dfs(int d, int aa, int bb) { 30 if (d == maxd + 1) { 31 if (!aa && better()) memcpy(ans, cur, sizeof(int) * (maxd + 1)); 32 return; 33 } 34 int fr = std :: max(getfirst(aa, bb), cur[d-1] + 1); 35 for (; ; fr++) { 36 if (aa * fr > (bb * (maxd - d + 1))) break; 37 cur[d] = fr; 38 int g = gcd(bb, fr); 39 int ta = (aa * fr - bb) / g; 40 int tb = (bb * fr / g); 41 dfs(d + 1, ta, tb); 42 } 43 } 44 int main () { 45 scanf("%d %d", &a, &b); 46 for (maxd = 1; ; maxd++) { 47 memset(ans, 127, sizeof(ans)); 48 dfs(1, a, b); 49 if (ans[1] > 0 && ans[1] != inf) { 50 int cur = 1; 51 while (ans[cur] > 0 && ans[cur] != inf) { 52 printf("%d ", ans[cur]); 53 cur++; 54 } 55 break; 56 } 57 } 58 59 return 0; 60 }