一本通【例题4】Addition Chains——题解
又是一道剪枝剪了半天的搜索题。。。题目传送
要充分利用题目中的约束条件:1、;2、对于每个k(1≤k≤m)k(1≤k≤m)满足ak=ai+aj(0≤i,j≤k−1)ak=ai+aj(0≤i,j≤k−1),这里i与j可以相等。由此可以推出a1一定=2(也能减少很多操作次数了吧)
还是先找找搜索过程要面临的状态和有关维度:目标数n,答案序列的长度limit,序列中的每个数ai,当前序列中的最后一个数last。
由于如果不对序列长度加以限制,普通的深搜便会“一发不可收拾”,所以这里用迭代加深搜索。
可行性剪枝考虑:
1、由于迭代加深搜索会把之前的状态全搜索一遍,所以应当限制一下limit的下界。注意到长度为k的序列能最大造出来的数为2k-1,所以序列最短应保证那个最大造出来的数>=n,预处理就行。
考虑一下搜索顺序:因为n是由小数加小数构造出来的,求最小的构造次数。因此应从大到小搜索。
考虑防等效冗杂:让从大到小枚举的两个数中的第1个正常枚举、第2个从第1个开始枚举。
继续考虑可行性剪枝:
2、当前枚举的序列里的两个数相加应大于last,只有这样才能继续搜索。
3(效率还不够,更近一步考虑一下未来):发现一个序列最大的增长方式即为让序列中最后一个数自己加自己,设这个数为a,进行k次这样的增长后序列中最后的一个数则为a*2k,每次增长操作都会增加一个数。对于当前长度为l的序列,如果last*2limit-l仍小于n,就回溯;等于n,那limit一定是答案;大于n时才继续搜索。2的幂次方可打表或预处理出。
最优性剪枝:找到答案就停止就行。
AC代码:
#include<iostream>
#include<cstdio> using namespace std; int n,a[],bj,cankao[],mi[]; void dfs(const int &limit,int k)//要填第k个(k从1开始)
{
if(bj) return;
if(k==limit)
{
for(int i=k-;i>=;i--)
for(int j=i;j>=;j--)
{
if(a[i]+a[j]==n)
{
a[k-]=n;
bj=;
return;
}
}
}
if(a[k-]*mi[limit-k+]<=n)//可行性剪枝3
{
if(a[k-]*mi[limit-k+]==n)
{
bj=;
for(int j=k-;j<limit;j++)
a[j]=a[j-]*;
}
return;
}
for(int i=k-;i>=;i--)
{
for(int j=i;j>=;j--)//防等效冗杂
if(a[i]+a[j]>a[k-])
{
if(a[i]+a[j]>=n) continue;//可行性剪枝2
a[k-]=a[i]+a[j];
dfs(limit,k+);
if(bj) return;
}
else
{
if(j==i) return;
break;
}
}
} void work()
{
bj=;
for(int len=cankao[n];len<=n;len++)
{
dfs(len,);
if(bj)
{
for(int i=;i<len;i++)
printf("%d ",a[i]);
putchar('\n');
return;
}
}
} void init()
{
int i=,step=;
while(i<=)
{
cankao[i]=step;
i*=;
step++;
}
for(i=;i<=;i++)
if(!cankao[i])
cankao[i]=cankao[i-];//以上为可行性剪枝1
i=,step=;
mi[]=;
for(int j=;j<=;j++)//2的幂次方的预处理
{
i*=;
mi[j]=i;
}
} int main()//预处理
{
init();
a[]=;a[]=;//注意序列下标0开始
scanf("%d",&n);
while(n)
{
if(n==)//处理特殊情况
{
putchar('');
putchar('\n');
}
if(n==)
cout<<"1 2\n";
if(n>=)
work();
scanf("%d",&n);
}
return ;
}
一本通【例题4】Addition Chains——题解的更多相关文章
- ZOJ1937:Addition Chains——题解
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1937 题目大意:创造一个数列,使得它: 1.单调不递减. 2.其中一个元素 ...
- 1443:【例题4】Addition Chains
1443:[例题4]Addition Chains 题解 注释在代码里 注意优化搜索顺序以及最优化剪枝 代码 #include<iostream> #include<cstdio&g ...
- 一本通例题埃及分数—题解&&深搜的剪枝技巧总结
一.简述: 众所周知,深搜(深度优先搜索)的时间复杂度在不加任何优化的情况下是非常慢的,一般都是指数级别的时间复杂度,在题目严格的时间限制下难以通过.所以大多数搜索算法都需要优化.形象地看,搜索的优化 ...
- 「一本通 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\). 数列中的一 ...
- UVA 529 Addition Chains(迭代搜索)
Addition Chains An addition chain for n is an integer sequence with the following four propertie ...
- [POJ2248] Addition Chains 迭代加深搜索
Addition Chains Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5454 Accepted: 2923 ...
- poj 2248 Addition Chains (迭代加深搜索)
[题目描述] An addition chain for n is an integer sequence with the following four properties: a0 = 1 am ...
- 一本通例题-生日蛋糕——题解<超强深搜剪枝,从无限到有限>
题目传送 显然是道深搜题.由于蛋糕上表面在最底层的半径确认后就确认了,所以搜索时的面积着重看侧面积. 找维度/搜索面临状态/对象:当前体积v,当前外表面面积s,各层的半径r[],各层的高度h[]. 可 ...
- 【题解】一本通例题 S-Nim
\(\color{purple}{Link}\) \(\text{Solution:}\) 这个题就是给\(Nim\)游戏做了一个限制. 考虑一下\(\text{SG}\)函数:给定的局面下对应的\( ...
随机推荐
- offsetof与container_of宏分析
offsetof宏:结构体成员相对结构体的偏移位置 container_of:根据结构体成员的地址来获取结构体的地址 offsetof 宏 原型: #define offsetof(TYPE, MEM ...
- argparse命令行传参
import argparse parser = argparse.ArgumentParser(description='manual to this script') # 创建解析器,及其描述 p ...
- kafka使用问题解决
java.lang.UnsupportedClassVersionError:org/apach/kafka/comon/utils/Utils:Unsupport major.minor versi ...
- XLS导出的服务器端配置方式
IIS支持excel导出: 1.开始—运行,然后键入DCOMCNFG; 2.组件服务—计算机—我的电脑—DCOM配置,这时弹出一个问注册的窗口,确定注册. 这时如果一切恢复正常了,不用往下操作了. 关 ...
- 56 道高频 JavaScript 与 ES6+ 的面试题及答案
56 道高频 JavaScript 与 ES6+ 的面试题及答案 :https://segmentfault.com/a/1190000020082089?utm_source=weekly& ...
- mongodb启动报错,child process failed, exited with error number 1
error: child process failed, exited with error number 1 第一次安装mongodb,随后启动一般不会出现上面的错误,出现这种错误的原因一般是mon ...
- PCIeの数据链路层与物理层详解
数据链路层(DLL,Data Link Layer)的主要作用是进行链路管理(Link Management).TLP错误校验.Flow Control(流控制)和Link功耗管理.不仅可以接收发送来 ...
- spring data jpa Specification 复杂查询+分页查询
当Repository接口继承了JpaSpecificationExecutor后,我们就可以使用如下接口进行分页查询: /** * Returns a {@link Page} of entitie ...
- 我国三大常用坐标系:北京54、西安80和WGS-84
转自:http://blog.sina.com.cn/s/blog_6dbe2d780100mwr5.html 我国三大常用坐标系:北京54.西安80和WGS-84 1.北京54坐标系(BJZ54)北 ...
- 关于Mysql 修改密码的记录
初次安装后完毕,使用管理员身份进入cmd界面, 输入" mysql -u root -p",出现"Enter password:",直接回车输入" s ...