您的位置:首页 > 其它

[CODEVS1288]埃及分数(迭代加深搜索)

2016-11-15 11:24 363 查看

题目描述

传送门

题解

迭代加深?好厉害的名字。

我之前一直以为迭代加深是用上一次搜索的有用的信息来更新下一次搜索的值。不过看起来不是这样的。

关键是题目中要求:加数少的比加数多的好。也就是说,我们应该优先考虑加数少的,先搜加数少的。如果要是普通的搜索的话,相当于是乱搜,并不能保证是最优解。

难道这就是迭代加深搜?

可以发现如果当前的分数是ab,如果想要将其分成x个分子为1的分数,并且分母越大越好的话,分母的范围应该为[1,⌈bxa⌉],并且,如果下一个选的分母是i的话,那么下一个分数应该是ab−i=ai−bbi,就这样接着搜索就行了。

一定要注意约分。

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
#define N 1005

LL a,b;int m;
LL now
,ans
;
bool flag;

LL gcd(LL a,LL b)
{
return (b)?gcd(b,a%b):a;
}
void yuefen(LL &a,LL &b)
{
LL t=gcd(a,b);
a/=t,b/=t;
}
void dfs(int x,int pre,LL a,LL b)
{
yuefen(a,b);
if (x==1)
{
if (a==1&&b>pre)
{
if (flag&&b>=ans[1]) return;
now[1]=b;
flag=1;
memcpy(ans,now,sizeof(now));
return;
}
return;
}
for (int i=pre,Max=ceil((double)b*x/a);i<=Max;++i)
{
now[x]=i;
dfs(x-1,i,i*a-b,i*b);
}
}
int main()
{
scanf("%lld%lld",&a,&b);
yuefen(a,b);
while (!flag)
{
++m;
dfs(m,1,a,b);
}
for (int i=m;i;--i) printf("%lld%c",ans[i]," \n"[i==1]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: