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

此题不难,主要思路便是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的更多相关文章
- 迭代加深搜索 C++解题报告 :[SCOI2005]骑士精神
题目 此题根据题目可知是迭代加深搜索. 首先应该枚举空格的位置,让空格像一个马一样移动. 但迭代加深搜索之后时间复杂度还是非常的高,根本过不了题. 感觉也想不出什么减枝,于是便要用到了乐观估计函数(O ...
- UVA 529 - Addition Chains,迭代加深搜索+剪枝
Description An addition chain for n is an integer sequence with the following four properties: a0 = ...
- vijos1308 埃及分数(迭代加深搜索)
题目链接:点击打开链接 题目描写叙述: 在古埃及.人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数.如:2/3=1/2+1/6,但不同意2/3=1/3+1/3,由于加数中有同样的.对于 ...
- UVA 1343 - The Rotation Game-[IDA*迭代加深搜索]
解题思路: 这是紫书上的一道题,一开始笔者按照书上的思路采用状态空间搜索,想了很多办法优化可是仍然超时,时间消耗大的原因是主要是: 1)状态转移代价很大,一次需要向八个方向寻找: 2)哈希表更新频繁: ...
- 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 ...
- POJ1129Channel Allocation[迭代加深搜索 四色定理]
Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14601 Accepted: 74 ...
- BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1800 Solved: 984[Submit][Statu ...
- 迭代加深搜索 POJ 1129 Channel Allocation
POJ 1129 Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14191 Acc ...
- 迭代加深搜索 codevs 2541 幂运算
codevs 2541 幂运算 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 从m开始,我们只需要6次运算就可以计算出 ...
随机推荐
- 这就涉及到ABAQUS历史输出中各能量变量的意义
ABAQUS中,对于很多动态问题,尤其像高速冲击模拟中,对结果评价很重要的一点就是要保证模型能量守恒,这就涉及到ABAQUS历史输出中各能量变量的意义,下面最各简单整理: ALLAE:人工伪应变能,六 ...
- 一个socket数量的问题
最近遇到一个问题,从业务上出现ftp异常: ftp .**.**.** ftp: connect: Cannot assign requested address 这台服务器上的socket统计如下: ...
- json字符串和json对象之间的转化
一.json字符串转化为json对象 二.json对象转化为json字符串
- Django Cache缓存系统学习--数据库缓存
Django是动态网站,用户每一次请求页面,服务器都会执行以下操作:数据库查询.渲染模版.执行业务逻辑,最后生成用户可查看的页面.当访问量比较大的时候,会消耗掉大量的资源,这时候就会考虑到缓存问题. ...
- docker学习-常用命令2
三.容器管理命令3.1 Docker commit 命令,从容器创建一个新的镜像.OPTIONS说明: -a :提交的镜像作者: -c :使用Dockerfile指令来创建镜像: -m :提交时的说明 ...
- 128bit 整数运算的实现
对于128bit的长整型运算,GCC提供了扩展类型:__int128.然而该类型不在C/C++语言的标准之中,并且对于不同种类的编译器,它的实现情况不同.因此,在编写相关的可移植程序时,我们有必要实现 ...
- HBase Master HA高可用
HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行. 所以这里要配置HBase高可用的话,只需要 ...
- 20. Valid Parentheses (JAVA)
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...
- mysql学习5:数据库设计
mysql学习5:数据库设计 本文转载:https://blog.51cto.com/9291927/2087925:原创为天山老妖S 一.数据库设计简介 按照规范设计,将数据库的设计过程分为六个阶段 ...
- linux尝试登录失败后锁定用户账户的两种方法
linux尝试登录失败后锁定用户账户的两种方法 更新时间:2017年06月23日 08:44:31 作者:Carey 我要评论 这篇文章主要给大家分享了linux尝试登录失败后锁定用户账 ...