An addition chain for n is an integer sequence <a0, a1,a2,...,am=""> with the following four properties:

  • 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

The input will contain one or more test cases. Each test case consists of one line containing one integer n (1<=n<=100). Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line containing the required integer sequence. Separate the numbers by one blank.

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 / 迭代加深)的更多相关文章

  1. 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, ...

  2. POJ 3083 BFS+DFS 40行

    题意:给你一个迷宫. 先输出当左转优先的时候走的路程长度,再输出当右转优先时走的路程长度,最后输出从起点到终点的最短路程长度. 嗯嗯 奴哥活跃气氛的题.随便写了写.. 此题 知道了思路以后就是水题了. ...

  3. POJ 3083 Bfs+Dfs

    注意求最短路的时候用Bfs. #include<iostream> #include<stdio.h> using namespace std; int w,h,ex,ey,s ...

  4. UVA - 1374 Power Calculus (dfs迭代加深搜索)

    题目: 输入正整数n(1≤n≤1000),问最少需要几次乘除法可以从x得到xn ?在计算过程中x的指数应当总是正整数. 思路: dfs枚举次数深搜 注意: 1.指数如果小于0,就退出当前的搜索 2.n ...

  5. POJ 2248 - Addition Chains - [迭代加深DFS]

    题目链接:http://bailian.openjudge.cn/practice/2248 题解: 迭代加深DFS. DFS思路:从目前 $x[1 \sim p]$ 中选取两个,作为一个新的值尝试放 ...

  6. poj 2248 Addition Chains (迭代加深搜索)

    [题目描述] An addition chain for n is an integer sequence with the following four properties: a0 = 1 am ...

  7. [POJ2248] Addition Chains 迭代加深搜索

    Addition Chains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5454   Accepted: 2923   ...

  8. UVA 529 - Addition Chains,迭代加深搜索+剪枝

    Description An addition chain for n is an integer sequence  with the following four properties: a0 = ...

  9. [POJ 2248]Addition Chains

    Description An addition chain for n is an integer sequence with the following four properties: a0 = ...

随机推荐

  1. μCUnit,微控制器的单元测试框架

    在MCU on Eclipse网站上看到Erich Styger在8月26日发布的博文,一篇关于微控制器单元测试的文章,有很高的参考价值,特将其翻译过来以备学习.原文网址:https://mcuone ...

  2. Confluence 6 配置 Windows 服务

    当你使用 Start Confluence Automatically on Windows as a Service 的方式启动的时候,你有下面 2 种方式来配置你的系统属性:通过 command ...

  3. 为 Confluence 6 配置发送邮件消息

    如何配置 Confluence 向外发送邮件: 进入  > 基本配置(General Configuration) > 邮件服务器(Mail Servers).这里列出了所有当前配置的 S ...

  4. Confluence 6 浏览默认的 Decorators

    在任何时候,你都可以使用 "Site Layouts" 页面中的 "View Default" 来浏览默认的 decorator 文件.模板浏览器允许你查看使用 ...

  5. MobileNet V2

    https://zhuanlan.zhihu.com/p/33075914 http://blog.csdn.net/u011995719/article/details/79135818 https ...

  6. GIL锁

    GIL锁                                                                           在CPython中,这个全局解释器锁,也称 ...

  7. 第七篇 python基础之函数,递归,内置函数

    一 数学定义的函数与python中的函数 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因 ...

  8. exec与match方法的区别

    http://www.cnblogs.com/xiehuiqi220/archive/2008/11/05/1327487.html var someText= "web2.0 .net2. ...

  9. python并发编程之多线程2------------死锁与递归锁,信号量等

    一.死锁现象与递归锁 进程也是有死锁的 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用, 它们都将无法推进下去.此时称系统处于死锁状态或系统 ...

  10. 如何在地址栏(title标签里)和收藏夹里 加上网站的标志ICO、LOGO图片

    第一步:首先你必须要制作一个看起来既清楚又容易辨识的.ico格式的小图片. 我们将图标的大小定义为16x16 像素.此外在制作图形文件的时候,你可能需要把色盘设定成只使用标准的 16 色 Window ...