又是一道剪枝剪了半天的搜索题。。。题目传送

要充分利用题目中的约束条件: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——题解的更多相关文章

  1. ZOJ1937:Addition Chains——题解

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1937 题目大意:创造一个数列,使得它: 1.单调不递减. 2.其中一个元素 ...

  2. 1443:【例题4】Addition Chains

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

  3. 一本通例题埃及分数—题解&&深搜的剪枝技巧总结

    一.简述: 众所周知,深搜(深度优先搜索)的时间复杂度在不加任何优化的情况下是非常慢的,一般都是指数级别的时间复杂度,在题目严格的时间限制下难以通过.所以大多数搜索算法都需要优化.形象地看,搜索的优化 ...

  4. 「一本通 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\). 数列中的一 ...

  5. UVA 529 Addition Chains(迭代搜索)

      Addition Chains  An addition chain for n is an integer sequence  with the following four propertie ...

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

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

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

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

  8. 一本通例题-生日蛋糕——题解<超强深搜剪枝,从无限到有限>

    题目传送 显然是道深搜题.由于蛋糕上表面在最底层的半径确认后就确认了,所以搜索时的面积着重看侧面积. 找维度/搜索面临状态/对象:当前体积v,当前外表面面积s,各层的半径r[],各层的高度h[]. 可 ...

  9. 【题解】一本通例题 S-Nim

    \(\color{purple}{Link}\) \(\text{Solution:}\) 这个题就是给\(Nim\)游戏做了一个限制. 考虑一下\(\text{SG}\)函数:给定的局面下对应的\( ...

随机推荐

  1. 获取fork+exec启动的程序的PID值

    问题背景     业务中有个场景需要自动起一个A程序(由于A程序与 sublime_text 启动后遇到的问题有相似之处,后文就用 sublime_text 来替代A程序,当A程序与 sublime_ ...

  2. IDEA工具与第三方工具集成

    IDEA工具与第三方工具集成 Tomcat部署 (一)配置Tomcat ->->->配置信息 常见问题: [1]注意部署异常:java.lang.OutOfMemoryError: ...

  3. Python3 字符编码到底是个什么鬼

    首先ASCII码是美国人自己给自己用的,只针对英文及一系列符号,凭想象预留了编码位置,不料有个东方大国文字过于复杂,预留根本不够,所以这个大国重新搞了个编码gb2312.gbk等,结果就是全世界各国都 ...

  4. centos6.9 安装mysql8

    centos6.9 安装 mysql8 # 安装mysql8 1.下载https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.16-2.el6.x86 ...

  5. P2672跳石头

    这是2015noip的一道二分答案的题目,看了题解才会,, 题目给出石头的位置并且让你踩着石头往前跳,最多删掉m个石头还可以顺利通过,求解最短跳跃距离的最大值. 那么二分什么呢:mid为跳跃的长度.那 ...

  6. int快读

    昨天偶然间看到CJ_tony的快读,所以便决定学习一下. 这个快读的原理就是:读入单个字符要比读入读入数字快,先读入字符,然后再转化成数字.(原理的话大学再研究) 代码: #include<io ...

  7. SCUT - 486 - 无向图上的点 - Dijkstra

    好像原题是这个?https://www.cnblogs.com/kanchuang/p/11120052.html 这个有解释:https://blog.csdn.net/wddwjlss/artic ...

  8. SCUT - 485 - 质因数计数 - 原根

    https://scut.online/p/485 给定a和n,求有多少个质数p,满足n是使得a^n=1 mod p成立的最小正整数. 翻译:求有多少个质数p,使得a模p的阶delta_m(a)是n ...

  9. neo4j 初探

    neo4j 初探 参考 转载:http://shomy.top/2018/06/08/neo4j-start/ 近期需要处理图数据,考察后打算使用neo4j, 相比其他一些图数据库,neo4j开源,跨 ...

  10. 点击Listview列头排序

    Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader) ListView1.Sorted = ...