埃及数字 迭代深搜

题目大意:给出一个真分数,要求写出他有哪几个埃及数字组成,在数目想等的情况,要求分母最小的那个

解题思路:深度逐层加深,从1开始递增下去,分母从1开始判断,设置一个分母的最大值,以免递归太多次

分子为a,分母为b,分母的最大值为min,该层的埃及数分母最小值为x,

剪枝:1.迭代层数大于等于当前最大次数时或x>=min,也就是分母已经加到最大值了,不必再递归下去了

2.如果 b % a等于零,b=b/a,b>x且b<min,表示后面有分母能表示到该值且不越界,找到了结束的条件了,将b赋值给min,后面的剪枝用得到

3.要求a/b > 1 / x ,也就是当a*x<b时,加上该埃及数就会超过所要求的值,循环寻找符合要求的最小x

4.当x<min时,且a*x<b(max_depth - depth)的数值才会符合,max_depth-depth表示还有几次可以递归,因为剪枝2已经找到了最后的值了,但不能确保那个值是最小的,所以将min改变后,就可以在更小的范围内找到最佳值

#include<cstdio>
#include<cstring>
const int maxn= 100;
int min;
int ans[maxn];
int out[maxn];
// depth表示递归了几次,max_depth表示最多的递归层数,a是分子,b是分母,x是所提供的最小的分母
void dfs(int depth, int max_depth, int a, int b,int x){
	if(depth >= max_depth || x >= min)
		return ;
	if(b % a == 0) {
		b = b/a;
		if(b < x || b >= min)
			return ;
		min = b;
		ans[depth] = b;
		memcpy(out,ans,(depth+1)*sizeof(int));//depth从0开始,所以要加上1
		return ;	
	}
	else {
		if(depth >= max_depth - 1) return ;
		while(a*x<=b && x<min)	x++;// a / b > 1 / x
		while(x<min) {
			if(a*x>=b*(max_depth-depth))	break;//因为后面的值都小于1/x,要确保在接下的max_depth-depth次中的和能为a/b
				ans[depth] = x;
				depth++;
				dfs(depth,max_depth,a*x-b,b*x,x+1);	
				depth--;	
				x++;
		}
	}
	return ;
}

int main() {
	int m,n;
	while(scanf("%d%d",&m,&n) != EOF && m+n) {
		min = 1000000;
		printf("%d/%d=",m,n);
	int i;
	for(i = 1;i <= 100; i++) {
		dfs(0,i,m,n,1);//i表示要递归的层数
		if(min < 1000000) 
			break;
	}
	for(int j = 0; j < i - 1 ; j++)
		printf("1/%d+",out[j]);
	printf("1/%d\n",out[i-1]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值