Addition Chains POJ - 2248 (bfs / dfs / 迭代加深)
- a0 = 1
- am = n
- a0 < a1 < a2 < ... < am-1 < am
- For each k (1<=k<=m) there exist two (not necessarily different) integers i and j (0<=i, j<=k-1) with ak=ai+aj
You are given an integer n. Your job is to construct an addition chain for n with minimal length. If there is more than one such sequence, any one is acceptable.
For example, <1,2,3,5> and <1,2,4,5> are both valid solutions when you are asked for an addition chain for 5.
Input
Output
Hint: The problem is a little time-critical, so use proper break conditions where necessary to reduce the search space.
Sample Input
5
7
12
15
77
0
Sample Output
1 2 4 5
1 2 4 6 7
1 2 4 8 12
1 2 4 5 10 15
1 2 4 8 9 17 34 68 77 题意:x【1】 = 1,x【m】 = n,给一个n,求出m最小的序列并输出 思路:这种最短的问题很容易直接想到bfs,但是写法可能不是很经常遇到,网上也有bfs写法的代码,就不给出代码了,主要就是bfs的路径记录,用个vector储存路径,并且每个路径记录前置路径,当达到答案n时,路径肯定最短,然后沿着记录的前置路径递归
其次可以有dfs,dfs的话有两种,一种是迭代加深,就是枚举搜索深度,如果没搜索到答案,就增加深度重新搜索,这种方法主要用在确定答案可以在较小深度的情况,时间复杂度类似bfs,但是空间复杂度小
最后就是dfs的剪枝版本了,剪枝的话其实是一个最优性剪枝(极限思想)和搜索顺序,搜索顺序正常从大到小,我们发现从打一个数x1递增到x2,所需要的最小步数是>=log(x2-x1),这样如果当前步数+log(x2-x1) > 当前记录的答案,这就说明这一定不是最优 迭代加深:
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std; int ans[];
bool vis[];
int n;
bool dfs(int last,int lim)
{
bool vis[];
memset(vis,,sizeof(vis));
if(last == lim)
{
if(ans[last] == n)
return ;
return ;
}
for(int i=last; i>=; i--)
{
for(int j=i; j>=; j--)
{
int tmp = ans[i] + ans[j];
if(tmp <= n && !vis[tmp])
{
if(tmp < ans[last])
return ;
vis[tmp] = ;
ans[last+] = tmp;
if(dfs(last+,lim))
return ;
}
}
}
return ;
} int main()
{
while(~scanf("%d",&n) && n)
{
ans[] = ;
for(int i=; i<=; i++)
{
if(dfs(,i))
{
for(int j=; j<=i; j++)
{
printf(j == i?"%d\n":"%d ",ans[j]);
}
break;
}
}
}
}
dfs剪枝:
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std; int ans[];
int t_ans[];
int b[];
bool vis[];
int n,m; void init()
{
m = n;
b[n] = ;
t_ans[] = ;
for(int i=n-;i>=;i--)
{
b[i] = b[min(i+i,n)] + ;
}
} void dfs(int last)
{
bool vis[];
memset(vis,,sizeof(vis));
if(last + b[t_ans[last]] > m)return;
if(t_ans[last] == n)
{
if(last <= m)
{
m = last;
for(int i=;i<=last;i++)
{
ans[i] = t_ans[i];
}
}
return;
}
for(int i=last; i>=; i--)
{
for(int j=i; j>=; j--)
{
int tmp = t_ans[i] + t_ans[j];
if(tmp <= n && !vis[tmp])
{
if(tmp < t_ans[last])
return;
vis[tmp] = ;
t_ans[last+] = tmp;
dfs(last+);
}
}
}
return;
} int main()
{
while(~scanf("%d",&n) && n)
{
init();
dfs();
for(int i=;i<=m;i++)
{
printf(i == m?"%d\n":"%d ",ans[i]);
}
}
}
Addition Chains POJ - 2248 (bfs / dfs / 迭代加深)的更多相关文章
- Q - 迷宫问题 POJ - 3984(BFS / DFS + 记录路径)
Q - 迷宫问题 POJ - 3984 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, ...
- POJ 3083 BFS+DFS 40行
题意:给你一个迷宫. 先输出当左转优先的时候走的路程长度,再输出当右转优先时走的路程长度,最后输出从起点到终点的最短路程长度. 嗯嗯 奴哥活跃气氛的题.随便写了写.. 此题 知道了思路以后就是水题了. ...
- POJ 3083 Bfs+Dfs
注意求最短路的时候用Bfs. #include<iostream> #include<stdio.h> using namespace std; int w,h,ex,ey,s ...
- UVA - 1374 Power Calculus (dfs迭代加深搜索)
题目: 输入正整数n(1≤n≤1000),问最少需要几次乘除法可以从x得到xn ?在计算过程中x的指数应当总是正整数. 思路: dfs枚举次数深搜 注意: 1.指数如果小于0,就退出当前的搜索 2.n ...
- POJ 2248 - Addition Chains - [迭代加深DFS]
题目链接:http://bailian.openjudge.cn/practice/2248 题解: 迭代加深DFS. DFS思路:从目前 $x[1 \sim p]$ 中选取两个,作为一个新的值尝试放 ...
- poj 2248 Addition Chains (迭代加深搜索)
[题目描述] An addition chain for n is an integer sequence with the following four properties: a0 = 1 am ...
- [POJ2248] Addition Chains 迭代加深搜索
Addition Chains Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5454 Accepted: 2923 ...
- UVA 529 - Addition Chains,迭代加深搜索+剪枝
Description An addition chain for n is an integer sequence with the following four properties: a0 = ...
- [POJ 2248]Addition Chains
Description An addition chain for n is an integer sequence with the following four properties: a0 = ...
随机推荐
- python面试30-40题
1.简述python引用计数机制 python垃圾回收主要以引用计数为主,标记-清除和分代清除为辅的机制,其中标记-清除和分代回收主要是为了处理循环引用的难题. 引用计数算法 当有1个变量保存了对 ...
- verilog-testbench 时钟和复位模板
/********************************************* ** Clocks & Reset ******************************* ...
- 放一点百度来的,常见的windowserror
0操作成功完成.1功能错误.2系统找不到指定的文件.3系统找不到指定的路径.4系统无法打开文件.5拒绝访问.6句柄无效.7存储控制块被损坏.8存储空间不足,无法处理此命令.9存储控制块地址无效.10环 ...
- python网络爬虫笔记(八)
一.pthon 序列化json格式 1.将python内置对象转换成json 模块,dumps()方法返回的是一个str,内容是标准的JSON,dump()方法可以直接吧JSON写入一个file-li ...
- CF919F
题意: Alice和Bob玩游戏,每人各有8张牌,牌的大小在0~4之间 每次操作,先手可以选择自己一张牌和对方一张牌求和后%5,将新的牌替代自己拿出的那张牌,以此类推,直到有一个人手中的牌全部是0,则 ...
- babel-cli 的使用
1.安装babel-cli npm i babel-cli -D 2.实现npm的初始化 npm init -y 3.配置package.json { "name": " ...
- centos6 防火墙iptables操作整理
使用语句 前言: iptables的启动文件位置再: /etc/init.d/iptables , srevice iptables调用的就是这里的执行文件 查看防火墙状态 service i ...
- python WebDriver如何处理右键菜单
WebDriver如何处理右键菜单 一.背景 在学习selenium webdriver的过程中,遇到这样一个问题.ActionChains类中提供了context_click的方法,它可以用来在we ...
- Red Language
官网地址:http://www.red-lang.org/ 源代码地址:https://github.com/red/red 通过github上的Readme,可以完成Hello World的学习 ...
- python 通用装饰器,带有参数的装饰器,
# 使用装饰器对有返回值的函数进行装饰# def func(functionName): # print('---func-1----') # def func_in(): # print(" ...