当前位置: 首页 > news >正文

HDU - 1455 Sticks(深搜+剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1455

说点题外话。这几天再次看搜索,找到一种新的理解方式,果然处理问题方便多了。

搜索的本质:利用递归实现很多个 for 循环,在每一次循环中不断筛选判断。

常见的搜索:

1,枚举搜索  (HDU 2533 - 八皇后问题,UVa 524 - 素数环,UVa 129 - Krypton Factor)

2,路径搜索  (HDU 1455 - Sticks,HDU 1010 - Tempter of the Bone)

上面举例的都是比较经典的一些例题了,比较难得可以推荐 USACO - 2.1 The Castle(http://train.usaco.org/usacoprob2?a=cV5k5rRXOz6&S=castle),会涉及好多搜索过程中的优化问题,找到最优解之类的。

简单说一下我所理解的上述两种搜索。

第一种:

枚举搜索: 特点是,每一步搜索即每一个递归即每一个for循环都可以枚举当前情况,根据情况进行筛选判断。

eg:按字典序输出n个数的全排列,每一步都可枚举,每一步都可判断能否枚举(即已经形成的排列集合里面无该数字),最后即可输出所有情况。

这种题 dfs 函数一般定义为 void 类型,因为每一步你就可以判断能否使用该枚举数,需要的是 return ;到上一步即可。

第二种:

路径搜索: 特点是无法确定的枚举出所有情况,充满着不确定因素。唯一能做的是顺藤摸瓜,一步一步去延伸,一步一步去扩展,一步一步去往深处走,这也正是 dfs 的本质。eg:走迷宫问题。知道起始点,规定步数,问在规定步数内是否可以到达。显然你无法把每一条路都枚举去进行判断。情况太多太复杂,靠人脑无法解决。这时候就可以考虑路径搜索这种情况。虽然不能将每一条路都可以枚举出来,但是可以将每一步都枚举出来(依据是:当前步可行),顺着这一条路走到头,这就是一种情况了。具体的可以看这个blog的题 HDU  - 1455 Sticks,下面有代码。  

这种题 dfs 一般定义为 bool 类型,因为你需要 return ture or false 来告诉之前的决策:" 哦!此路不通,你要从上一步开始重新找路了"。    

这种问题通常不难理解,只要接触5道左右基本可以掌握。难就难在如何进行剪枝,因为递归开销非常大。  这里有一种我理解的剪枝 ,和本题很类似。倘若某一决策涉及到之前使用过的决策且之前使用过的决策不能达到目的,那么就进行剪枝。大致描述是这样,不是很清楚,具体还要看题啊。QAQ~

总而言之,我最大的收获是:将搜索理解成n重for循环,然后每一重筛选判断。

 

#include <iostream>
#include <cstring>
#include <algorithm>
#define MAX 55
using namespace std;
/*************************************************************************************************************
            题意:讲的大致是几根原本长度相同的木棒,然后被某人当出气筒剪啊剪啊,剪成好几段,
                   然后,好吧,这时间一长记性就差了,忘了原来这堆木棒的长度
            思路:
            1,将给定木棒排序,原木棒长度 <= 木棒和 && 原木棒长度 >= 这一堆木棒的最大值。
            2,在区间内进行深搜即可,这几天深搜理解的也比较到位了。
            3, 29行的剪枝绝对不能少!一般人想不到
*************************************************************************************************************/

int a[MAX],visit[MAX],n;

bool dfs(int SUM,int sum,int cur)
{
    if(cur == n && sum == SUM)    return true;
    if(sum == SUM)    sum=0;

    for(int i = n;i >= 1;i --){
        if(!visit[i] && sum+a[i] <= SUM){
            visit[i]=1;
            if(dfs(SUM,sum+a[i],cur+1))
                return true;
            visit[i]=0;

            if(sum == 0)        //剪枝:如果当前搜索时,前边的长度为0,而第一根没有成功的使用,
                                //      说明第一根始终要被废弃,所以这种组合必定不会成功
                return false;
            while(a[i] == a[i-1])
                i--;
        }
    }
    return false;
}

int main()
{
    while(cin>>n,n != 0)
    {
        int SUM=0,i;

        for(i = 1;i <= n;i ++){
            cin>>a[i];
            SUM+=a[i];
        }
        sort(a+1,a+n+1);

        for(i = a[n];i <= SUM;i ++){
            if(SUM%i)    continue;

            memset(visit,0,sizeof(visit));
            if(dfs(i,0,0)){
                cout<<i<<endl;
                break;
            }
        }
    }
    return 0;
}


 



 

转载于:https://www.cnblogs.com/Jstyle-continue/p/6351969.html

相关文章:

  • perl 递归两例
  • Tomcat学习总结(3)——Tomcat优化详细教程
  • memchached你知道和不知道的事
  • PHP教程,Linux教程光盘
  • C++走向远洋——51(数组类运算的实现)
  • C++模板的特化详解(函数模版特殊,类模版特化)
  • java读取文件中的内容写入excel中
  • 怎样解决asp.net.mvc上传附件超过长度问题?
  • 开发中的[绝对路径]与[相对路径]
  • Eclipse debug时 鼠标移动到变量时 自动显示变量只
  • SVM-非线性支持向量机及SMO算法
  • Spark版本定制第10天:流数据生命周期和思考
  • 《构建之法》观后感
  • Git 使用规范流程(转)
  • mongodb 2.4升级至3.2
  • 【node学习】协程
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【剑指offer】让抽象问题具体化
  • Android Studio:GIT提交项目到远程仓库
  • css属性的继承、初识值、计算值、当前值、应用值
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • java概述
  • Java精华积累:初学者都应该搞懂的问题
  • JS 面试题总结
  • log4j2输出到kafka
  • Unix命令
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 产品三维模型在线预览
  • 前端js -- this指向总结。
  • 前端面试总结(at, md)
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 一、python与pycharm的安装
  • 正则学习笔记
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 阿里云服务器如何修改远程端口?
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #define 用法
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (算法二)滑动窗口
  • (转)我也是一只IT小小鸟
  • (轉)JSON.stringify 语法实例讲解
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .net core Swagger 过滤部分Api
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .NET基础篇——反射的奥妙
  • @GlobalLock注解作用与原理解析