这种最优解和深度有关的,可以使用迭代加深对dfs进行优化。
但显然普通的IDDFS效率还是不能满足这题的要求,因为直接枚举分母明显是不行的(可能达到1e7),那么我们可以对IDDFS进行上下界剪枝。
下界优化1:我们可以发现,题目要求升序排列,因此可以从上次分母+1开始枚举
下界优化2: 我们发现枚举的分数一定要小于x/y,所以可以得到1/i<x/y,变化得到y<xi
然后在这两个值中取一个大的值即可。
上界优化:设当前还差res个数到maxdep,由于一个比一个小,那么我们可以得到res/i>x/y
变换得res*y>x*i,即可进行上界优化。
然后IDDFS爆搜即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define N 1000005 6 #define int long long 7 using namespace std; 8 int read() 9 { 10 int x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} 13 return x*f; 14 } 15 int dwn(int x,int y) 16 { 17 for(int i=2;;i++)if(x*i>y)return i; 18 } 19 int a,b,n,t,anss,ans[N],s[N]; 20 bool dfs(int res,int x,int y) 21 { 22 if(res==1) 23 { 24 if(x==1&&y>s[t]&&(anss==0||y<ans[anss])) 25 { 26 anss=++t;s[t]=y; 27 for(int i=1;i<=t;i++)ans[i]=s[i]; 28 t--; 29 return 1; 30 } 31 return 0; 32 } 33 bool getans=0; 34 for(int i=max(dwn(x,y),s[t]+1);res*y>x*i;i++) 35 { 36 int yy=y/__gcd(y,i)*i; 37 int xx=x*(yy/y)-yy/i; 38 s[++t]=i; 39 if(dfs(res-1,xx/__gcd(xx,yy),yy/__gcd(xx,yy)))getans=true; 40 t--; 41 } 42 return getans; 43 } 44 signed main() 45 { 46 freopen("fraction.in","r",stdin); 47 freopen("fraction.out","w",stdout); 48 ios::sync_with_stdio(0); 49 cin>>a>>b; 50 int xx=__gcd(a,b); 51 a/=xx;b/=xx; 52 if(a==1) 53 { 54 cout<<b<<endl; 55 return 0; 56 } 57 s[0]=1; 58 for(int i=2;;i++) 59 { 60 t=0; 61 if(dfs(i,a,b)) 62 { 63 for(int i=1;i<=anss;i++)cout<<ans[i]<<" "; 64 cout<<endl; 65 return 0; 66 } 67 } 68 }