LOJ P10022 埃及分数 题解

每日一题 day62 打卡

Analysis

这道题一看感觉很像搜索,但是每次枚举x∈(1,10000000)作为分母显然太蠢了。

所以我们要想办法优化代码。

优化一:迭代加深

优化二:

我们确定了搜索方式,现在就要确定搜索的上下界。

因为现在搜索的分数一定要比剩下的值小,于是有:

1/i​<x/y

上界满足 y<xi

设还有k个分数,因为枚举的分母是单调递增的,所以分数的值是单调递减的,可得后k个分数的值严格小于k/i,而这个值一定要比当前剩下的值大,

于是有:

k/i>x/y
下界满足 ky>xi

 

优化想好了之后就可以安心码代码~~~

注意:一些细节在代码中有注释

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define int long long
 6 #define INF 2147483647
 7 #define maxn 100000+10
 8 #define rep(i,s,e) for(register int i=s;i<=e;++i)
 9 #define dwn(i,s,e) for(register int i=s;i>=e;--i)
10 using namespace std;
11 inline int read()
12 {
13     int x=0,f=1;
14     char c=getchar();
15     while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
16     while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
17     return f*x;
18 }
19 void write(int x)
20 {
21     if(x<0) {putchar('-'); x=-x;}
22     if(x>9) write(x/10);
23     putchar(x%10+'0');
24 }
25 int a,b;
26 int t,len;
27 int s[maxn],ans[maxn];
28 inline int calc(int x,int y)
29 {
30     rep(i,2,INF)
31         if(x*i>y)
32             return i;
33 }
34 bool dfs(int rest,int x,int y)//因为要方便判断枚举的长度可不可以,所以选择bool类型的搜索 
35 {
36     if(rest==1)
37     {
38         if(x==1&&y>s[t]&&(len==0||y<ans[len]))
39         {
40             len=++t;
41             s[t]=y;
42             rep(i,1,t) ans[i]=s[i];
43             --t;
44             return true;
45         }
46         return false;
47     }
48     bool flag=false;
49     for(register int i=max(s[t]+1,calc(x,y));rest*y>i*x;++i)
50     {
51         int now_x=x*i-y;
52         int now_y=y*i;//nx/xy=x/y-1/i; 
53         int mod=__gcd(now_x,now_y);
54         now_x/=mod;
55         now_y/=mod;
56         s[++t]=i;
57         if(dfs(rest-1,now_x,now_y)==true) flag=true; 
58         --t;
59     }
60     return flag;
61  } 
62 signed main()
63 {
64     a=read();b=read();
65     int mod=__gcd(a,b);
66     a/=mod;
67     b/=mod;
68     if(a==1) {write(b); return 0;}
69     s[0]=1;
70     rep(i,2,INF)
71     {
72         t=0;
73         if(dfs(i,a,b)==true)
74         {
75             rep(j,1,len) 
76             {
77                 write(ans[j]); 
78                 putchar(' ');
79             }
80             break;//第一次搜到的答案一定是最优 
81         }    
82     }
83     return 0;
84 }

如有失误请各位大佬斧正(反正我不认识斧正是什么意思)

猜你喜欢

转载自www.cnblogs.com/handsome-zyc/p/12076449.html