【codevs1288】埃及分数(迭代加深搜索)

我也不知道为什么样例输出答案不是5 9 9....

有时候,答案的搜索树深度过大,甚至根本无法估测,使得我们很容易超时。

这时往往用到的是迭代加深搜索——限制本次搜索的层数,每次比上次多一层,这样不会很浪费时间,因为当前层的状态数相对于之前的来说少的多。

本道题是个典型的例子

代码还进行了一个剪枝:若剩下的层数全部选同一个数还不够,就break掉

#include<bits/stdc++.h>
#define ll long long
const int N=100005; 
using namespace std;
ll a,b;
inline int Get(int x,int y)	//返回1/c<=x/y c的最大值
{
	return y/x+1;
} 
inline void Remove(ll &x,ll &y)
{
	ll g=__gcd(x,y);
	x/=g; y/=g;
}
ll tmp[N],ans[N];
inline int Better(int n)
{
//	for(int i=2;i<=n;i++)	if(tmp[i]==tmp[i-1]) return 0;
	for(int i=n;i>=1;i--)
		if(tmp[i]!=ans[i])
			return tmp[i]<ans[i]||ans[i]==0;
	return 0;
}
int dfs(int limit,int dep,int last,ll x,ll y)
{
	if(dep==limit)
	{
		if(y%x)	return 0;
		tmp[dep]=y/x;
		if(Better(dep))	memcpy(ans,tmp,sizeof(ans));
		return 1;
	}
	int begin=max(last,Get(x,y)),f=0;
	for(int next=begin;;next++)
	{
		if((limit-dep+1)*y<=x*next)	break;
		tmp[dep]=next;
		ll u=x*next-y,v=y*next;
		Remove(u,v);
		if(dfs(limit,dep+1,next+1,u,v)) f=1; 
	}
	return f;
}
int main()
{
	cin>>a>>b;
	Remove(a,b); int u=Get(a,b);
	for(int d=2;;d++)
	{
		memset(ans,0,sizeof(ans));
		if(dfs(d,1,u,a,b))	
		{
			for(int i=1;i<=d;i++)
				cout<<ans[i]<<" ";
			return 0;
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值