Addition Chains 

An addition chain for n is an integer sequence  with the following four properties:

  • a0 = 1
  • am = n
  • a0<a1<a2<...<am-1<am
  • For each k ( ) there exist two (not neccessarily different) integers i and j ( ) 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 Specification

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

Output Specification

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

题意:给定一个n,要求求出这样一条最短的满足以下条件的加法链:

1、起点为1,终点为n, 2、递增 3、每个数字可以找到该链中其他两个数字相加组成

思路:本来我的思路是直接暴力的。。果断超时。大一点的数据都跑不出来。。原因是如果直接搜。加法链的个数没有限制,直接要多很多不必要的搜索。

然后在网上看到了一种迭代搜索法。是先确定一个最小的条件。在本题中,仔细观察不难发现,如果每次都是以两倍的趋势上升,那么加法链将会最短。那么由最短的这个条件开始,进行搜索,如果这个条件搜不到,就把条件+1,继续搜索。直到出现一个满足条件的方案结束。。

不过这题要多一个优化。举个例子。比如n为16时。最短条件为5.前3个数字为1 2 3时候,最大将只能为1 2 3 6 12,是到不了16的,因此可以发现。如果一个数字,不断乘2直到到达那个条件。如果小于n,那么这条搜索多余的,直接返回。

#include <stdio.h>
#include <string.h> int n;
int ci;
int judge;
int out[10005];
void dfs(int num)
{
if (judge)
return;
if (num == ci)
{
if (out[num] == n)
{
judge = 1;
}
return;
}
for (int i = num; i >= 0; i --)
{
for (int j = num; j >= i; j --)
{
if (out[i] + out[j] > out[num] && out[i] + out[j] <= n)
{
int sum = out[i] + out[j];
for (int k = num + 1; k <= ci; k ++)
{
sum *= 2;
}
if (sum < n)
continue;
out[num + 1] = out[i] + out[j];
dfs(num + 1);
if (judge)
return;
}
}
}
}
int main()
{
while (scanf("%d", &n) != EOF && n)
{
judge = 0;
ci = 0;
int sb = 1;
while (sb < n)
{
sb *= 2;
ci ++;
}
while (1)
{
memset(out, 0, sizeof(out));
out[0] = 1;
dfs(0);
if (judge)
break;
ci ++;
}
for (int i = 0; i < ci; i ++)
{
printf("%d ", out[i]);
}
printf("%d\n", out[ci]);
}
return 0;
}

但是这个写法还是有一定问题的。。我测试了一些数据。如1111.还是要跑好一会的。。不过没超时。估计是数据的问题。。然后看了别人的代码。写了另一个。这个方法是先确定一个上限。每次找到后,把上限进行缩小。直到找到最小为止。。

#include <stdio.h>
#include <string.h> int n;
int end;
int num[35];
int output[35];
void dfs(int star)
{
if (star < end)
{
for (int i = star - 1; i >= 0; i --)
{
int sum = num[star - 1] + num[i];
if (sum <= n)
{
num[star] = sum;
if (num[star] == n && end > star)
{
for (int j = 0; j <= end; j ++)
{
output[j] = num[j];
}
end = star;
}
int sb = sum;
for (int j = star + 1; j <= end; j ++)
sb *= 2;
if (sb < n)
continue;
dfs(star + 1);
} }
}
}
int main()
{
while (scanf("%d", &n) != EOF && n)
{
memset(num, 0, sizeof(num));
memset(output, 0, sizeof(output));
if (n == 1)
{
end = 0;
output[0] = 1;
}
else
end = 30;
num[0] = 1;
dfs(1);
for (int i = 0; i < end; i ++)
printf("%d ", output[i]);
printf("%d\n", output[end]);
}
return 0;
}

UVA 529 Addition Chains(迭代搜索)的更多相关文章

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

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

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

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

  3. 1443:【例题4】Addition Chains

    1443:[例题4]Addition Chains 题解 注释在代码里 注意优化搜索顺序以及最优化剪枝 代码 #include<iostream> #include<cstdio&g ...

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

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

  5. 「一本通 1.3 例 4」Addition Chains

    Addition Chains 题面 对于一个数列 \(a_1,a_2 \dots a_{m-1},a_m\) 且 \(a_1<a_2 \dots a_{m-1}<a_m\). 数列中的一 ...

  6. [POJ 2248]Addition Chains

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

  7. Addition Chains POJ - 2248 (bfs / dfs / 迭代加深)

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

  8. 【POJ2248、LOJ#10021】 Addition Chains

    事先预警:由于我太蒻了,本做法只能在POJ.LOJ等小数据(N<=100)平台上通过,在UVa(洛谷)上大数据并不能通过 戳我获得更好的观看效果 本题不用看,爆搜就是了,但是纯爆搜显然会爆时间, ...

  9. C++解题报告 : 迭代加深搜索之 ZOJ 1937 Addition Chains

    此题不难,主要思路便是IDDFS(迭代加深搜索),关键在于优化. 一个IDDFS的简单介绍,没有了解的同学可以看看: https://www.cnblogs.com/MisakaMKT/article ...

随机推荐

  1. 作为Qt 合作伙伴的V-Play,比大家都领先了一步 planet.qt.io

    今天发布博客,将Flappy Bird和其它的小游戏移植到Respberry PI了 http://planet.qt.io/ planet.qt.io 的repo: https://coderevi ...

  2. MySQL分组数据

    分组 理解分组能够看例如以下一个样例,首先我们打印出products表例如以下 从上面的表中能够看出.每一个vendor都有若干个产品,那么怎么一次统计每一个vendor有多少个产品呢? 这里就能够使 ...

  3. ACM第三次比赛UVA11877 The Coco-Cola Store

      Once upon a time, there is a special coco-cola store. If you return three empty bottles to the sho ...

  4. 【转】android加载大量图片内存溢出的三种解决办法

    方法一: 在从网络或本地加载图片的时候,只加载缩略图. /** * 按照路径加载图片 * @param path 图片资源的存放路径 * @param scalSize 缩小的倍数 * @return ...

  5. 探究绑定事件的this指向以及event传参的小问题

    this指向 直接上代码,凑合着看 <input type="button" onclick="page()" value="点我"& ...

  6. 操作VCF卡片信息的第三方jar包:ez-vcard

    ez-vcard https://github.com/mangstadt/ez-vcard 目前最新的版本已经更新到0.9.8 起初使用该jar包的时候,是0.9.3,当时遇到一个很尴尬的问题, 就 ...

  7. Android TextView(同时显示图片+文字)

    见上图:需要图片和文字 在一起 之前的做法是用两个控件组成 <LinearLayout> <ImageView /> <TextView /> </Linea ...

  8. 9天快速入门java

    Java入门教程[9天快速入门JAVA] §1.3.简单的Java程序 下面我们先介绍两个简单的Java程序,并对其进行分析. 例1.1. public class HelloWorldApp{//a ...

  9. Oracle单表的简单查询

    Oracle单表的简单查询 查看表结构 desc emp; 查询所有列 Select * from emp; 查找所以部门编号(查指定的列) select deptnofrom emp; 查找编号不同 ...

  10. java调用163邮箱发送邮件

    1:注册一个163邮箱,http://mail.163.com 调用发送邮件代码,查询smtp.163.com,作为发送邮件的服务器ip,类似的邮箱服务器应该也可以. MailSenderInfo m ...