埃及分数

这种最优解和深度有关的,可以使用迭代加深对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 }
View Code
原文地址:https://www.cnblogs.com/szmssf/p/11730113.html