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. Confluence 6 嵌入的 H2 数据库

    为了让你的 Confluence 在安装成功后就可以使用而不需要使用任何外部的数据库,Confluence 使用一个嵌入的 H2 数据库. 当你选择对 Confluence 进行评估和测试的时候,H2 ...

  2. Confluence 6 MySQL 测试你的数据库连接

    在你的数据库设置界面,有一个 测试连接(Test connection)按钮可以检查: Confluence 可以连接你的数据库服务器 数据库字符集,隔离级别和存储引擎是正确的 你的数据库用户有正确的 ...

  3. MySQL数据库之安装

    一.基础部分 1.数据库是什么 之前所学,数据要永久保存,比如用户注册的用户信息,都是保存于文件中,而文件只能存在于某一台机器上. 如果我们不考虑从文件中读取数据的效率问题,并且假设我们的程序所有的组 ...

  4. 1005:Number Sequence(hdu,数学规律题)

    Problem Description A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1 ...

  5. 从认识面向对象到构造函数的标准写法(构造函数的继承、多态、ECMA6中新代替语法class) - 下

    笔记一个包含:认识面向对象.构造函数的封装.继承.多态.ECMA6中新代替语法class 下:包括构造函数的继承.多态.ECMA6中新代替语法class 构造函数的继承 从父一级延续下来的属性和功能( ...

  6. Centos6.10部署TeamViewer

    1.在官网下载支持Linux系统的包,建议下载TeamViewer12的包,官网URL:https://www.teamviewer.com/cn/download/linux/ 2.将下载的软件包导 ...

  7. spring-data-mongo的MongoTemplate开发

    spring-data-mongo的MongoTemplate开发 1.在实体类Customer.Java中引入注解表明转换方式 @Document   //文档 public class Custo ...

  8. IDEA中tomcat的部署

    创建一个项目就要部署tomcat

  9. python练习册 0002随机生成验证

    这个题需要用到random库的方法,不用就会忘,暂把random库的常用方法贴出来 import random import string # 随机整数 # randint(a, b),生成a~b之间 ...

  10. 使用openssl创建一个自签名https证书,并配置到nginx里面

    公司内网也有这个需求,就简单实现一下. 参考的都是网上的方案,一次过. 1,使用openssl建立服务器私钥(需要输入密码,请记住这个密码)生成RSA密钥 >openssl genrsa -de ...