zoukankan      html  css  js  c++  java
  • 题解 SP7579 YOKOF

    SP7579 YOKOF - Power Calculus

    迭代加深搜索

    • DFS每次选定一个分支,不断深入,直至到达递归边界才回溯。这种策略带有一定的缺陷。试想以下情况:搜索树每个节点的分支数目非常多,并且问题的答案在某个较浅的节点上。如果深搜在一开始选错了分支,就很可能在不包含答案的深层子树上浪费许多时间

    • 此时,我们可以从小到大限制搜索的深度,如果在当前深度限制下搜不到答案,就把深度限制增加,重新进行一次搜索,这就是迭代加深思想。

    • 虽然该过程在深度限制为d时,会重复搜索第1~d-1层的节点,但是当搜索树节点分支数目较多时,随着层数的深入,每层节点数会呈指数级增长(这样时间主要取决于最后一次搜索的时间),这点重复搜素与深层子树的规模相比,实在是小巫见大巫了。

    • 总而言之,当搜索树规模随着层次的深入增长很快,并且我们能够确保答案在一个较浅层的节点时,就可以采用迭代加深的深度优先搜索算法来解决问题。

    分析

    显然有解,连续乘n次x总是能得到x^n的,只是可能不是最优解。

    操作次数最小时有搜索深度最小,而理论上搜索深度可以是无穷的,这种情况下就可以使用迭代加深了。

    (以上by Chelly)

    #include<cstdio>
    using namespace std;
    int n,ans,a[15];
    inline bool dfs(int step,int x) {//x为当前构造的指数
    	if (step>ans || x<=0 || x<<(ans-step)<n) return 0;
        //当step超过限定步数,指数为非正数,或者x自乘(ans-step)次仍小于n(可行性剪枝),则直接返回
    	if (x==n || x<<(ans-step)==n) return 1;
    	a[step]=x;
    	for (register int i=0; i<=step; i++)
    		if (dfs(step+1,x+a[i]) || dfs(step+1,x-a[i]))//乘或除以一个构造过的数
    			return 1;
    	return 0;
    }
    int main() {
    	while(scanf("%d",&n) && n) {
            //用x乘除构造x^n,相当于从1加减构造出指数n
    		for (ans=0; !dfs(0,1); ans++);//迭代加深搜索
    		printf("%d
    ",ans);
    	}
    }
    
  • 相关阅读:
    checkpoint出现的时间
    快速断开当前数据库的所有连接的方法
    SQLSERVER备份数据库的时候copy only选项的意思
    SQLSERVER备份事务日志的作用
    SQLSERVER使用密码加密备份文件以防止未经授权还原数据库
    Windows Azure终于到来中国了
    SQLSERVER2005的安装目录结构(下)
    SQLSERVER2005的安装目录结构(上)
    给大家分享两款正在使用的reflector插件
    一套内容采集系统 解放编辑人员
  • 原文地址:https://www.cnblogs.com/Randolph68706/p/11301652.html
Copyright © 2011-2022 走看看