首页 > 其他分享 >P1763 埃及分数 题解

P1763 埃及分数 题解

时间:2023-02-24 13:34:46浏览次数:54  
标签:分数 frac P1763 题解 int step 搜索 return

做完后发现很多题解都是有些细节问题的,对于向上与向下取整非常混乱。

第一次做迭代加深搜索的题,记录一下。

所谓迭代加深搜索,就是在求搜索树的深度的问题中,枚举层数,取最优解。

然而广搜其实感觉上能做到,但广搜在分支太多的情况下,容易爆栈,所以推出了迭代加深搜索。

本题一来肯定想到爆搜,很好的拿到 \(10pts\)。

然后学习到了迭代加深搜索,因为本题优先使分解的数个数最少,相当于求 \(1e7\) 叉搜索树的最小深度,所以可以优先进行分层搜索。

但貌似没什么用,仍然是 \(10pts\)。

考虑剪枝。

1.最优性剪枝

在同一层的情况下,若枚举到的最大分母大于了之前答案的最大分母,那么本次肯定不能更新答案,直接退出。

2.无效性剪枝

对于枚举中分数的和已大于目标分数,不可能达到,舍去。

3.优化搜索顺序

从小到大进行搜索,避免重复。

进行了三次优化后分数依然没变,为 \(10pts\)。

此时应该发现了,本题搜索的最大关键是因为搜索分支过多,导致效率低下。所以最重要的应该是想办法去处大量的无效性分支,所以应该进行第二次无效性剪枝。

首先是搜索上界,由于搜索顺序被优化,搜索是从小到大进行,所以如果前面的分数过小,后面的分数再大,也无法凑成目标分数。

所以我们可以列出一个式子

\(\frac{1}{i}> \frac{a}{b}\div step \hspace{0.1cm}\text{(其中}\hspace{0.1cm}step \hspace{0.1cm}\text{代表剩余需要分解的分数个数)}\)

两边倒数后

\(i<\frac{b\times step}{a}\)

其实后来发现可以取等,虽然会因为有重复数字造成影响,但我们不妨假设

\(i=\frac{b\times step}{a}\)

那么取了分数 \(\frac{1}{i}\) 后,必定与目标分数相等,那么这个深度在枚举此深度之前就已经搜到可行解了,此次解必定不是最优,直接舍去,所以可以取等。

\(i\le\frac{b\times step}{a}\)

那么右式可以直接向下取整,不需要利用精度去计算。

处理上界完毕后得分为 \(30pts\)。

模拟题目中有一个例子 \(a=59,b=211\) 可以发现因为现分数和大于目标分数的情况十分多,所以只有这样回溯不是最优的,我们应该处理下界。

下界就更简单了,当 \(\frac{1}{i}>\frac{a'}{b'}\hspace{0.3cm}\frac{a'}{b'}\hspace{0.1cm}\text{(代表减去之前枚举过的分数后的剩余分数)}\) 时,直接减去这种情况。

所以下界就是第一个满足 \(\frac{1}{i}\le \frac{a'}{b'}\) 的 \(i\)。

取倒数后 \(i\ge\frac{b'}{a'}\)。

可以取等的证明同上,右式可以向上取整,不用处理精度问题。

然后就AC了,十分不容易。

#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
int a,b,t[1005],p[1005];
int ans;
int gcd(int x,int y)
{
	if(y==0)return x;
	return gcd(y,x%y);
}
bool dfs(int step,int bef=1,int x=a,int y=b)
{
	if(bef>t[1])return 0;
	if(step==0&&x==0)
	{
		for(int i=1;i<=ans;i++)t[i]=p[i];
		return 1;
	}
	if(step==0)return 0;
	bool flag=0;
	bef=max(bef,(y+x-1)/x);
	for(int i=bef;(y*step)/x>=i;i++)
	{
		int num=gcd(y,i);
		if(num>1e7)continue;
		p[step]=i;
		bool s=dfs(step-1,i+1,x*i/num-y/num,y/num*i);
		flag|=s;
	}
	return flag;
}
signed main()
{
	scanf("%lld%lld",&a,&b);
	for(int i=1;i<=1000;i++)t[i]=1e9;
	while(++ans)if(dfs(ans))break;
	for(int i=ans;i>0;i--)printf("%lld ",t[i]);
	return 0;
}

标签:分数,frac,P1763,题解,int,step,搜索,return
From: https://www.cnblogs.com/gmtfff/p/p1763.html

相关文章

  • P4048 [JSOI2010]冷冻波 题解
    首先很好想到我们应该预处理出来每一个巫妖王能攻击到的精灵。那么这就是一个几何题。对于每一组精灵与巫妖王,设巫妖王坐标为\((x_1,y_1)\),精灵坐标为\((x_2,y_2)\)。......
  • P7221 [JSOI2010] 蔬菜庆典 题解
    本题解在求无解的情况下优化了下。通过分析样例,我们可以发现如果一个节点有多个Dlihc,那么这些Dlihc对应的权值必须一样,否则可以无限延伸下去。因为一号节点没有Tnera......
  • P3195 [HNOI2008]玩具装箱 题解
    首先先写dp方程非常简单\(\mathit{f}_{i}=\min(\mathit{f}_{j}+(\mathit{c}_{i}+i-j-1-L-\mathit{c}_{j})^2)\)(其中\(\mathit{c}_{i}\)表示长度前缀和)然后发现括号......
  • U259394 Gmt丶FFF 的基环树 题解
    题目链接:传送门之所以评黑,是因为实在是太难调了。(又回调了)。对于有$40%$的数据,$n\le3000$,这部分我们可以暴力删边,然后暴力求直径即可。那么对于$100%$的数据:首先......
  • P3977 [TJOI2015]棋盘 题解
    前制知识引导状态压缩动态规划:[P1896[SCOI2005]互不侵犯](https://www.luogu.com.cn/problem/P1896)矩阵加速优化:[P1962斐波那契数列](https://www.luogu.com.cn/prob......
  • vscode格式化和保存代码与eslint有冲突问题解决(亲测有效)
    1.问题描述vscode安装了eslint插件,在使用Vue的时候格式化和保存代码都会爆红2.原因因为在使用Vue进行开发我们一般都安装了Vetur插件来对.vue文件进行处理,Vetur自带了......
  • 云原生|kubernetes|CKA真题解析-------(6-10题)
    第六题:service配置 解析:考察两个知识点:deployment控制器内的port命名暴露一个pod内的端口到新建的服务内的这里有一个需要注意的地方,没有告诉你deployment控制器在哪个name......
  • Windows 技术篇 - 远程桌面连接不保存密码、每次都要输入密码问题解决
    https://blog.csdn.net/qq_38161040/article/details/120013883通过 gpedit.msc 打开本次组策略编辑器。选择 模板管理-系统-凭据分配-允许分配保存的凭据用......
  • 【题解】ARC156 A-C
    神仙的ARC。A.Non-AdjacentFlip题目分析:就是一个分类讨论,主要就是讨论一下只有\(2\)个\(1\)的情况。自己手模一下应该很好理解。代码:点击查看代码#include<b......
  • [luogu P4705玩游戏] 题解
    P4705玩游戏题解题意概括给出两个序列\(a_0,a_2,\cdotsa_{n-1}\),\(b_0,b_2,\cdotsb_{m-1}\),从两个序列中各等概率的选出两个数\(a_i,b_j\),对于\(k\in[1,t]\)......