此题不难,主要思路便是IDDFS(迭代加深搜索),关键在于优化。

一个IDDFS的简单介绍,没有了解的同学可以看看:

https://www.cnblogs.com/MisakaMKT/articles/10767945.html

我们可以这么想,设当前规定长度为M,题目要求得出的数为N。

在搜索中,当前的步数为step,当前的数列为 数组a。

首先来确定思路,便是在以得出的数列a中枚举每两个数相加得出sum,然后继续搜索下一步。

初步的代码便是:

void iddfs(int step) {
for(int i=1;i<=step;i++)
for(int j=1;j<=step;j++) {
a[step+1]=a[i]+a[j];
iddfs(step+1);
}
}

但是我们需要保证的数列应该是有序上升的,所以需要保证a[step+1]必须大于a[x]。

void iddfs(int step) {
for(int i=1;i<=step;i++)
for(int j=1;j<=step;j++) {
a[step+1]=a[i]+a[j];
if(a[step+1]>a[step]) continue;
iddfs(step+1);
}
}

但这样还不够,为了满足样例的需求,应该要从大到小来枚举加数。为了避免重复搜,还可以让j=i。

void iddfs(int step) {
for(int i=step;i>=1;i--)
for(int j=i;j>=1;j--) {
a[step+1]=a[i]+a[j];
if(a[step+1]<a[step]) continue;
iddfs(step+1);
}
}

现在可以发现可以简单的过样例了,但最后一个样例的时间却非常的长。所以我们应该要思考优化了。

可以发现序列的最后一个数最大都只能是\(a_{step}*2^{M-step}\)。为什么呢,因为要使最后结果最大,选的都必须是序列中最大的两个数,也就是最后一个数。结果算出来便就是\(a_{step}*2^{M-step}\)。

那么我们的优化就很简单了,如果\(a_{step}*2^{M-step}\)是小于N的,那就根本不可能有解,就需要舍去。这便是这道题剪枝的思想。

最后的代码:

#include <iostream>
#include <cstring>
using namespace std; #define N 200 int a[200],n,len,flag; void dfs(int step) {
if(step>len) return ;
if(step==len && a[step]==n) {//找到了解,输出
for(int i=1;i<=step;i++)
printf("%d ",a[i]);
puts("");
flag=1;
return ;
}
if(a[step]>=n) return ;
for(int i=step;i>=1;i--)
for(int j=step;j>=i;j--) {
if(a[i]+a[j]>a[step] && a[i]+a[j]<=n ) {
a[step+1]=a[i]+a[j];
int sum=a[i]+a[j];
for(int k=step+2;k<=len;k++)
sum*=2;
if(sum<n) continue;
dfs(step+1);
if(flag) return ;
}
}
} int main() {
while(cin>>n) {
len=0;
if( !n ) return 0;
memset(a,0,sizeof(0));
a[1]=1;a[2]=2,a[3]=4;
int m=1;
while(m<n) {//这句加不加都无所谓,对时间复杂度影响不大
m*=2;//len完全可以从1开始
len++;
}
for(len;;len++) {
dfs(1);
if(flag) break;
}
flag=0;
}
}

include

include

using namespace std;

define N 200

int a[200],n,len,flag;

void dfs(int step) {

if(step>len) return ;

if(steplen && a[step]n) {

for(int i=1;i<=step;i++)

printf("%d ",a[i]);

puts("");

flag=1;

return ;

}

if(a[step]>=n) return ;

for(int i=step;i>=1;i--)

for(int j=step;j>=i;j--) {

if(a[i]+a[j]>a[step] && a[i]+a[j]<=n ) {

a[step+1]=a[i]+a[j];

int sum=a[i]+a[j];

for(int k=step+2;k<=len;k++)

sum*=2;

if(sum<n) continue;

dfs(step+1);

if(flag) return ;

}

}

}

int main() {

while(cin>>n) {

len=0;

if( !n ) return 0;

memset(a,0,sizeof(0));

a[1]=1;a[2]=2,a[3]=4;

int m=1;

while(m<n) {

m*=2;

len++;

}

for(len;;len++) {

dfs(1);

if(flag) break;

}

flag=0;

}

}

C++解题报告 : 迭代加深搜索之 ZOJ 1937 Addition Chains的更多相关文章

  1. 迭代加深搜索 C++解题报告 :[SCOI2005]骑士精神

    题目 此题根据题目可知是迭代加深搜索. 首先应该枚举空格的位置,让空格像一个马一样移动. 但迭代加深搜索之后时间复杂度还是非常的高,根本过不了题. 感觉也想不出什么减枝,于是便要用到了乐观估计函数(O ...

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

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

  3. vijos1308 埃及分数(迭代加深搜索)

    题目链接:点击打开链接 题目描写叙述: 在古埃及.人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数.如:2/3=1/2+1/6,但不同意2/3=1/3+1/3,由于加数中有同样的.对于 ...

  4. UVA 1343 - The Rotation Game-[IDA*迭代加深搜索]

    解题思路: 这是紫书上的一道题,一开始笔者按照书上的思路采用状态空间搜索,想了很多办法优化可是仍然超时,时间消耗大的原因是主要是: 1)状态转移代价很大,一次需要向八个方向寻找: 2)哈希表更新频繁: ...

  5. UVA 11212 Editing a Book [迭代加深搜索IDA*]

    11212 Editing a Book You have n equal-length paragraphs numbered 1 to n. Now you want to arrange the ...

  6. POJ1129Channel Allocation[迭代加深搜索 四色定理]

    Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14601   Accepted: 74 ...

  7. BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1800  Solved: 984[Submit][Statu ...

  8. 迭代加深搜索 POJ 1129 Channel Allocation

    POJ 1129 Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14191   Acc ...

  9. 迭代加深搜索 codevs 2541 幂运算

    codevs 2541 幂运算  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 从m开始,我们只需要6次运算就可以计算出 ...

随机推荐

  1. 这就涉及到ABAQUS历史输出中各能量变量的意义

    ABAQUS中,对于很多动态问题,尤其像高速冲击模拟中,对结果评价很重要的一点就是要保证模型能量守恒,这就涉及到ABAQUS历史输出中各能量变量的意义,下面最各简单整理: ALLAE:人工伪应变能,六 ...

  2. 一个socket数量的问题

    最近遇到一个问题,从业务上出现ftp异常: ftp .**.**.** ftp: connect: Cannot assign requested address 这台服务器上的socket统计如下: ...

  3. json字符串和json对象之间的转化

    一.json字符串转化为json对象 二.json对象转化为json字符串

  4. Django Cache缓存系统学习--数据库缓存

    Django是动态网站,用户每一次请求页面,服务器都会执行以下操作:数据库查询.渲染模版.执行业务逻辑,最后生成用户可查看的页面.当访问量比较大的时候,会消耗掉大量的资源,这时候就会考虑到缓存问题. ...

  5. docker学习-常用命令2

    三.容器管理命令3.1 Docker commit 命令,从容器创建一个新的镜像.OPTIONS说明: -a :提交的镜像作者: -c :使用Dockerfile指令来创建镜像: -m :提交时的说明 ...

  6. 128bit 整数运算的实现

    对于128bit的长整型运算,GCC提供了扩展类型:__int128.然而该类型不在C/C++语言的标准之中,并且对于不同种类的编译器,它的实现情况不同.因此,在编写相关的可移植程序时,我们有必要实现 ...

  7. HBase Master HA高可用

    HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行. 所以这里要配置HBase高可用的话,只需要 ...

  8. 20. Valid Parentheses (JAVA)

    Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...

  9. mysql学习5:数据库设计

    mysql学习5:数据库设计 本文转载:https://blog.51cto.com/9291927/2087925:原创为天山老妖S 一.数据库设计简介 按照规范设计,将数据库的设计过程分为六个阶段 ...

  10. linux尝试登录失败后锁定用户账户的两种方法

    linux尝试登录失败后锁定用户账户的两种方法 更新时间:2017年06月23日 08:44:31   作者:Carey    我要评论   这篇文章主要给大家分享了linux尝试登录失败后锁定用户账 ...