1. 程式人生 > 其它 >P1763 埃及分數

P1763 埃及分數

感謝所有AC

 

傳送門

思路

     在不清楚 a/b 可以分解多少個分數時,搜尋樹的深度是未知的,分母可以是無窮大,所以需要對搜尋樹的深度進行一定的限制來進行搜尋。

      迭代加深搜尋就是這樣的一種搜尋,在DFS上加上深度引數來限制搜尋的深度,當深度超過限制後直接返回,不再向下搜尋。

      在主體函式中迴圈深度,對各深度 dfs 直到找到答案推出迴圈。注意資料開 long long,搜尋過程中儲存路徑。

程式碼

#include<iostream>
using namespace std;
typedef long long ll;
ll ans[20], res[20];
int a, b, dep;
bool flag;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
void dfs(ll a, ll b, int d) {
	if (d > dep)return;
	if (a == 1 && b > res[d - 1]) {
		res[d] = b;
		if (!flag || res[d] < ans[d])
			for (int i = 1; i <= dep; i++)
				ans[i] = res[i];
		flag = 1;
		return;
	}
	ll l = max(b / a + 1, res[d - 1] + 1);
	ll r = b * (dep - d + 1) / a;
	if (r >= ans[dep] && flag)
		r = ans[dep] - 1;
    //列舉的上下限的最優性剪枝
	for (ll i = l; i < r; i++)
		if (i > res[d - 1]) {
			res[d] = i;
			ll g = gcd(a * i - b, b * i);
			dfs((a * i - b) / g, b * i / g, d + 1);
		}
}
int main(void)
{
	ios::sync_with_stdio(false);
	cin >> a >> b;
	int c = gcd(a, b);
	a /= c, b /= c;
	for (dep = 1; dep <= 10; dep++)//迭代加深
	{
		dfs(a, b, 1);
		if (flag) {
			for (int i = 1; i <= dep; i++)
				cout << ans[i] << " ";
			break;
		}
	}
	return 0;
}