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 = ...
随机推荐
- kafka消息存储与partition副本原理
消息的存储原理: 消息的文件存储机制: 前面我们知道了一个 topic 的多个 partition 在物理磁盘上的保存路径,那么我们再来分析日志的存储方式.通过 ll /tmp/kafka-logs/ ...
- 【python】kafka在与celery和gevent连用时遇到的问题
前提:kafka有同步,多线程,gevent异步和rdkafka异步四种模式.但是在与celery和gevent连用的时候,有的模式会出错. 下面是我代码运行的结果. 结论:使用多线程方式! 使用同步 ...
- Python基础之多态与多态性
切记:不要将多态与多态性这二者混为一谈,只要分开,就会很明朗了. 一.多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承). 比如:动物分为人类.狗类.猪类(在定义角 ...
- JSP 指令 脚本元素 表达式 声明
一.page指令 1. 可以使用page指令来控制JSP转换器转换当前JSP页 面的某些方面.例如,可以告诉JSP用于转换隐式对象 out的缓冲器的大小.内容类型,以及需要导入的Java 类型,等等. ...
- web.xml中的ContextLoaderListener和DispatcherServlet区别
ContextLoaderListener和DispatcherServlet都会在Web容器启动的时候加载一下bean配置. 区别在于: DispatcherServlet一般会加载MVC相关的be ...
- linux基础练习题(1)
Linux命令作业(关卡一) 练习题1 理解操作系统的作用,以及各种操作系统的不同 要求: 简述什么是OS 简述应用程序.硬件.OS的关系 列举出3种常见的操作系统 简述Ubuntu和Linux的关系 ...
- nodejs 环境安装
参考网站 http://www.runoob.com/nodejs/nodejs-http-server.html https://github.com/nodesource/distribution ...
- base | Thread类、ThreadData结构体 、CurrentThread命名空间
__thread __thread是GCC内置的线程局部存储设施,存取效率可以和全局变量相比.__thread变量每一个线程有一份独立实体,各个线程的值互不干扰.可以用来修饰那些带有全局性且值可能变, ...
- 小程序wx.getUserInfo获取用户信息方案介绍
问题模块 框架类型 问题类型 API/组件名称 终端类型 操作系统 微信版本 基础库版本 API和组件 - - - - 背景 小程序一个比较重要的能力就是获取用户信息,也就是使用 wx.g ...
- Zabbix 3.2.6通过SNMP和iDRAC监控DELL服务器
https://www.cnblogs.com/saneri/p/7772641.html