ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

浅谈迭代加深(iddfs)

2021-02-13 20:02:47  阅读:159  来源: 互联网

标签:return 浅谈 迭代 int 45 iddfs depth num ans


引子

迭代加深搜索的实质就是限制搜索层数的暴搜。在了解DFS的基础上,iddfs其实是很好理解的。只是需要多一个枚举层数的过程再在搜索里面判断一下层数。

gm的版子(伪代码)

IDDFS ( int current_depth  ,  int max_depth )   //当前深度,最大深度
{
       if ( current_depth > max_depth ) return ;
       if ( 找到答案 ) { 输出答案 ; (exit(0) ;  ||  return ;) }
       for each ( 当前节点的儿子节点 )
       {
 	IDDFS ( current_depth+1  ,  max_depth ) ;
       }   
}
//在main函数中,调用IDDFS
for ( int  i = min_depth ; ; i++ )
{
       IDDFS ( 0 , i ) ;
}

例题

埃及分数

题目描述

在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数。如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的。对于一个分数a/b,表示方法有很多种,但是哪种最好呢?首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。
如:19/45=1/3 + 1/12 + 1/180
19/45=1/3 + 1/15 + 1/45
19/45=1/3 + 1/18 + 1/30,
19/45=1/4 + 1/6 + 1/180
19/45=1/5 + 1/6 + 1/18.
最好的是最后一种,因为1/18比1/180,1/45,1/30,1/180都大。
给出a,b(0<a<b<1000),编程计算最好的表达方式

思路

这道题用暴搜是基本无法实现的。首先我们并不知道需要多少个分数,也不知道最大的分母有多大。其递归层数和深度都是无限的。

因为我们只需要求到最优解,所以通过枚举深度(从小到大)我们是可以对递归层数进行限制的。那么如何枚举每一个分母的大小呢?
假设我们需要枚举的分数为\(\frac{a}{b}\)
当前分数的分母一定大于 \(\frac{b}{a}\)的所以下界为\(\frac{b}{a}\),那我们如何求上界呢?
因为我们限制了递归的层数,假设递归的最深层数为\(x\), 当前层数为\(y\), 那么 \(frac{x - y}{k}\) 一定\(>\) \(\frac{a}{b}\)的。
进行移项后,我们可以得到 \(k <= (y - x + 1) \times \frac{b}{a}\)

代码

#include <cstdio>
#include <cstring>
#include <algorithm> 
#include <cstdlib>//好东西 
#define int long long
using namespace std;
const int maxn = 1005;

int gcd(int x, int y){
	if(y == 0)return x;
	return gcd(y, (x % y));
}
int a, b;
int maxt;
int ans[maxn * maxn];
int ans2[maxn * maxn];
bool flag;
int t;
int sum;

//int Fibonacci(int a, int b, int num){
//	if(b % a == 0)return num;
//	int Gcd = gcd(a, b);
//	a /= Gcd;
//	b /= Gcd;
//	ans2[num] = (b / a + 1);
//	a = (b / a) * a - b;
//	b *= (b / a);
//	return Fibonacci(a, b, num + 1);
//}

void dfs(int a, int b, int num, int maxt){
	if(num > maxt)return;
	int Gcd = gcd(a, b);
	a /= Gcd;
	b /= Gcd;
//	if(b % a == 0){
//		ans[num] = b / a;
//		if(ans[num] > ans[num - 1]){
//			if(num == sum && num <= maxt && ans[num] < ans[sum]){
//				for(int i = 1; i <= num; i ++){
//					ans2[i] = ans[i];
//				}
//			}
//			if(num <= maxt && (num < sum || !flag)){
//				for(int i = 1; i <= num; i ++){
//					ans2[i] = ans[i];
//				}
//			}
//			flag = 1;
//			sum = num;
//		}
//		return;
//	}
	if(b % a == 0 && (b / a) > ans[num - 1]){
		ans[num] = b;
		if(!flag || ans[num] < ans2[num]){
			for(int i = 1; i <= num; i ++){
				ans2[i] = ans[i];
			}
			flag = 1;
			sum = num; 
		}
		return;
	}
	int s = b / a + 1;
	if(s <= ans[num - 1])s = ans[num - 1] + 1;
	int t = (maxt - num + 1) * (b / a);
	if(flag && t >= ans2[sum])t = ans2[sum] - 1; 
	for(int i = s; i <= t; i ++){
		ans[num] = i;
		dfs(a * i - b, b * i, num + 1, maxt);  
	}
}
signed main() {
	scanf("%lld %lld", &a, &b);
//	int t = Fibonacci(a, b, 1);
	for(int i = 1; ; i ++){
		flag = 0;
		dfs(a, b, 1, i);
		if(flag){
			for(int j = 1; j <= sum; j ++){
				printf("%lld ", ans2[j]);
			}
			return 0;
		}
	}
	return 0;
}

标签:return,浅谈,迭代,int,45,iddfs,depth,num,ans
来源: https://www.cnblogs.com/Nefelibata/p/14400908.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有