题目:http://www.sqyoj.club/problem.php?id=1130
分析:题目中指出加数少的优于加数多的,故采用IDA*迭代加深搜索。
普通的dfs,不知道要搜索多少层,从而会TLE,为避免TLE,肯定需要限定搜索层数,比如10层,然后一样的,进行优化,也可以解决本题。
IDA*框架如下:
void dfs(int deepth){
if(deepth==DEP){
...;
return;
}
...;
}
int main(){
...;
for(DEP=1;;DEP++){
...;
dfs(deepth);
...;
if(...)break;
}
}
为避免TLE,本题需要上下界剪枝优化、排除等效冗余,详见代码注释。
要开long long。
AC代码:
//埃及分数:IDA* 迭代加深搜索
#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
int DEP,minn;
int s[100],tot,ans[500][101];
long long a,b;
long long gcd(long long x,long long y){
return y==0?x:gcd(y,x%y);
}
void dfs(int t,ll a,ll b){
if(t==DEP){//IDA*标志
s[t]=b;
if(a==1&&s[t]>s[t-1]){//排除等效冗余。可以少探索一层
++tot;
for(int i=1;i<=t;i++)ans[tot][i]=s[i];
if(s[t]<minn)minn=s[DEP];
}
return;
}
for(int i=max(s[t-1]+1,int(b/a+1));i<=int((DEP-t+1)*b/a);i++){//上下界剪枝
s[t]=i;
ll aa=a*i-b,bb=b*i,GCD=gcd(aa,bb);
aa=aa/GCD;bb=bb/GCD;
dfs(t+1,aa,bb);
}
}
void print(){
for(int i=1;i<=tot;i++)
if(ans[i][DEP]==minn){
cout<<ans[i][1];
for(int j=2;j<=DEP;j++)cout<<' '<<ans[i][j];
cout<<endl;
}
}
int main(){
cin>>a>>b;
minn=1e9;tot=0;
for(DEP=1;;DEP++){//IDA*标志
s[0]=1;
dfs(1,a,b);//deepth,a,b
if(ans[1][1])break;
}
print();
return 0;
}
/*
input:
59 211
output:
4 36 633 3798
6 9 633 3798
*/