UVA12558 Egyptian Fractions (HARD version)(埃及分數)
阿新 • • 發佈:2018-09-09
names clear for 下界 rac algorithm bool .com scan
傳送門
題目大意
給出一個真分數 a/b,要求出幾個互不相同的埃及分數(從大到小),使得它們之和為 a/b
(埃及分數意思是分子為1的分數,詳見百度百科)
如果有多組解,則分數數量少的優先
如果分數數量一樣則分母最大的要盡量小,如果最大的分母同樣大,則第二大的分母盡量小,以此類推
為了加大難度,會給出k個不能作為分母的數
(2<=a,b<=876,k<=5 並且 a,b 互質)
首先想的是數論,但是呢
推不出來...
然後發現a,b好像不大
貌似可以搜索
但是呢
不知道上界...
那就叠代加深搜索唄
然後想想怎麽剪枝
如果知道 a/b,要怎麽求出最小 k 使 1/k < a/b 呢(註意符號)
易知 a/b 為真分數 ,a,b,k均為整數 所以 a<b 所以必定有整數 x,y 使得 x*a+y=b 且y<a 所以可得 int(b/a)=int( (x*a+y) /a )=int(x*a/a)+int(y/a) = x 因為 int(b/a)<=b/a,int(b/a)=x 所以 int(b/a)+1>b/a,x+1 > b/a 所以1/(x+1) < a/b 又 1/int(b/a)=1/x >=a/b 所以 x+1就是最小的 k 使得 1/k < a/b 所以 k=int(b/a) + 1 證明完畢
知道了 k 的下界,那還要求 k 的上界
顯然每次求的分母肯定要比上一次大(題目要求)
所以如果後面所有的分母都為 k ,加起來還沒有當前要求的數大,那就不要再搜下去了,再下去也不會有結果的
然後就可以搜了,至於判斷是否可用我用的是set
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<set> using namespace std; const int N=1e5+7; set <longlong> p; long long t,A,B,n,mxdep; long long ans[N],w[N]; bool flag; inline long long gcd(long long a,long long b) { return b ? gcd(b,a%b) : a; }//gcd是為了約分 inline bool pd() { for(int i=mxdep;i;i--) if(ans[i]!=w[i]) return ans[i]&&ans[i]<w[i]; return 0; }//判斷答案是否更優 inline void dfs(long long dep,long long a,long long b,long long mi) { if(dep==mxdep) { if(b%a||(b<(mi-1)*a+1)||p.count(b/a)) return;//判斷合法性 //如果a/b可化為 1/k 的形式並且 1/k 可以選 w[dep]=b/a; if(pd()) return;//判斷答案是否更優 memcpy(ans,w,sizeof(w)); flag=1;//更新 return; } mi=max(mi,b/a+1);//求出下界 for(long long i=mi;i;i++) { if( (mxdep-dep+1)*b<=i*a ) return;//上界 if(p.count(i)) continue;//判斷合法 w[dep]=i;//記錄路徑 long long xa=a*i-b,xb=i*b;//通分 long long z=gcd(xa,xb); dfs(dep+1,xa/z,xb/z,i+1);//約分,向下一層 } } int main() { cin>>t; for(long long i=1;i<=t;i++) { flag=0; mxdep=1; cin>>A>>B>>n; long long c; p.clear();//細節 while(n--) scanf("%lld",&c),p.insert(c);//存儲不合法的數 while(mxdep++) { memset(ans,0,sizeof(ans)); dfs(1,A,B,B/A+1); if(flag) break; }//叠代加深 printf("Case %lld: %lld/%lld=1/%lld",i,A,B,ans[1]); for(int i=2;i<=mxdep;i++) printf("+1/%lld",ans[i]); printf("\n"); } return 0; }
UVA12558 Egyptian Fractions (HARD version)(埃及分數)