完全按照题解的剪枝,40pts,救助!
  • 板块P1763 埃及分数
  • 楼主halehu
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/4/1 20:07
  • 上次更新2023/10/23 19:44:02
查看原帖
完全按照题解的剪枝,40pts,救助!
365777
halehu楼主2023/4/1 20:07
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,maxdep = 1,p[15],v[15],k;
bool pan(ll x,ll y,ll t,ll num){
     //t代表还能最多加几次单位分数 
     //num代表当前单位分数的分母 
	if(num > k) return false;
	//如果目前的最小单位分数分母大于已知,剪掉 
	ll c,d;
	if(x == 0 && y == 0) c = t, d = num;
	else c = x * num + y * t,d = y * num;
	//当前单位分数加最多次得到的和仍然小于a/b,剪掉 
	if(c * b < a * d) return false;
	else return true;
}
ll gcd(ll x,ll y){
	if(x == 0) return y;
	else return gcd(y % x,x);
}
void dfs(ll dep,ll x,ll y){
	if(dep > maxdep) return;
	ll num = p[dep - 1] + 1; 
	while(pan(x,y,maxdep - dep + 1,num)){
		ll xx,yy;
		if(x == 0 && y == 0) xx = 1,yy = num;
		else xx = x * num + y,yy = y * num;
		//ll g = gcd(xx,yy);
		//xx /= g,yy /= g;
		//cout<<xx<<" "<<yy<<endl;
		if(xx * b == yy * a){
			p[dep] = num;
			if(v[dep] > p[dep]){
				for(int i=1;i<=dep;i++) v[i] = p[i];
				k = v[dep];
			}  
			return;
		}
		else if(xx * b < yy * a){
			p[dep] = num;
			dfs(dep + 1,xx,yy);
		}
		num ++;
	}
	return;
}
int main(){
	cin>>a>>b;
	while(maxdep <= 10){
		memset(p,0,sizeof p);
		memset(v,127/3,sizeof v);
		k = 1e10;
		p[0] = 1;
		dfs(1,0,0);
		if(v[1] < 1e10){
			for(int i=1;i<=maxdep;i++)
			    cout<<v[i]<<" ";
			break;
		}
		maxdep ++;
	}
}

rt,加了约分后甚至只有30pts,剪枝的注释已经写上,大佬劳驾看下!

2023/4/1 20:07
加载中...