AcWing 167. 木棒(DFS + 剪枝优化)

news2024/11/13 9:28:58

AcWing 167. 木棒(DFS + 剪枝优化)

  • 一、问题
  • 二、分析
    • 1、整体分析
    • 2、剪枝优化
      • (1)优化搜索顺序
      • (2)排除等效冗余
      • (3)可行性剪枝
      • (4)最优性剪枝
      • (5)其他优化
  • 三、代码

一、问题

在这里插入图片描述

二、分析

1、整体分析

这道题的数据范围非常小,在这种情况下,大概率就是一道指数级别的算法,即我们的暴力枚举DFS。

这道题中让我们求的是最小长度,所以我们从小开始枚举木棒的长度,利用DFS去暴力枚举看看有没有可能枚举出一种合法的方案。如果可以的话,说明这就是最小长度,如果不可以的话,我们就继续枚举长度。

但我们的长度枚举的时候,只需要枚举所有木棍总和的约数即可。因为只有我们的木棒长度能够整除所有木棍总和的时候,才有可能是答案。

2、剪枝优化

剪枝优化总共分为下面几个方面:
优化搜索顺序,排除等效冗余,可行性剪枝,最优性剪枝,记忆化搜索。

(1)优化搜索顺序

对于一个木棍而言,它要么就是自己再去创造一个新的木棒,要么就接在已有的木棒的后面。每一种选择的背后都是一棵搜索树。选择越多,说明树的节点越多,时间越长。

因此,我们需要减少选择的个数,从而减少搜索树中的子树。所以,我们可以将木棍从大到小排序,从大开始枚举。这样对于我们的一个木棒长度而言,我们的木棍越长,那么留给后续木棍的选择空间就越小。从而减少了后续木棍的选择,进而减少了节点数目。

(2)排除等效冗余

对于一个木棒而言,组成该木棒的木棍之间的顺序是没有要求的,因为这些内部木棍之间的顺序变化并不会一引起木棒长度的变化。

也就是说,我们的DFS中要做的是组合型枚举,而不是排列型枚举。

那么什么是组合型枚举和排列型枚举呢?不懂得同学可以去看一下作者之前得文章:

三类最基础的DFS问题

(3)可行性剪枝

这里先给出结论,在某个新的木棒中,在“尝试接入的第一个木棍”的递归分支就返回失败的话,那么就直接判断失败即可,不需要再去更换当前的第一根木棍继续枚举。

为什么呢?

在这里插入图片描述

在上面这个图中,我们的第四组新的木棒是我们的目标,我们当前接入了该木棒内的第一根小木棍A,那么为了成功凑出正确长度的木棒。在后续的DFS中,我们就会去利用剩余的小木棍去枚举所有包含木棍A的可能方案

如果当前分枝返回了失败,意思就是所有利用剩余的小木棍并且包含小木棍A的可能方案都无法凑出一个正确的长度。

由于我们必须用完所有的小木棍,所以我们后续的方案中肯定有一个包含A的方案,但是我们已经知道是不可能了,所以就不用再去枚举后面的方案了。

(4)最优性剪枝

在这里插入图片描述

如果当前的木棒在接入最后一根木棒A后,这根木棒的长度恰好满足了条件,但是在拼接剩余木棒的时候失败了。那么回溯后,我们就会更换当前的最后一个木棒A。由于我们木棍的长度是从大到小的,所以用来代替A的必定是更短的多根木棍,假设是B和C。

那么A和B + C是等价的。

也就是说,我们用A的地方,都能用B和C代替。但是,我们用B和C的地方不一定能用A代替,因为我们的A是没法拆分的。也就是说B+C的组合能拼出更多的可能。

那么在结尾是A的时候,我们利用B和C加剩余木棍都没能拼好,那么现在用A和剩余木棍也一定不会拼好。

(5)其他优化

如果一个长度在当前木棒中无法组成正确的长度的话,那么后续和当前长度相同的木棍也不会构成正确的长度,所以直接略掉即可。

三、代码

#include<bits/stdc++.h>
using namespace std;
const int N = 70;

int n;
int w[N];
int sum, length;
bool st[N];

bool dfs(int u, int cur, int start)
{
    if (u * length == sum) return true;
    if (cur == length) return dfs(u + 1, 0, 0);

    for (int i = start; i < n; i ++ )
    {
        if (st[i] || cur + w[i] > length) continue;

        st[i] = true;
        if (dfs(u, cur + w[i], i + 1)) return true;
        st[i] = false;

        if (!cur || cur + w[i] == length) return false;

        int j = i;
        while (j < n && w[j] == w[i]) j ++ ;
        i = j - 1;
    }

    return false;
}

int main()
{
    while (cin >> n, n)
    {
        memset(st, 0, sizeof st);
        sum = 0;

        for (int i = 0; i < n; i ++ )
        {
            cin >> w[i];
            sum += w[i];
        }

        sort(w, w + n);
        reverse(w, w + n);

        length = 1;
        while (true)
        {
            if (sum % length == 0 && dfs(0, 0, 0))
            {
                cout << length << endl;
                break;
            }
            length ++ ;
        }
    }

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/343864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ASEMI低压MOS管AO3401封装,AO3401图片

编辑-Z ASEMI低压MOS管AO3401参数&#xff1a; 型号&#xff1a;AO3401 封装&#xff1a;SOT-23 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;30V 栅源电压&#xff08;VGS&#xff09;&#xff1a;12V 连续漏电流&#xff08;I&#xff09;&#xff1a;4.2A …

K_A12_004 基于STM32等单片机采集人体红外感应(HC-SR501)模块串口与OLED0.96双显示

K_A12_004 基于STM32等单片机采集人体红外感应&#xff08;HC-SR501&#xff09;模块串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明模块工作原理:对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCHC-SR501模块1.2、STM32F103C8T6HC-SR501模块…

docker-compose概述与简单编排部署

一、Docker-compose 简介Docker-Compose项目是基于Python开发的Docker官方开源项目&#xff0c;负责实现对Docker容器集群的快速编排。Docker-Compose将所管理的容器分为三层&#xff0c;分别是 工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&#…

MySQL学习笔记——CSDN学习记录九:数据库存储引擎

存储引擎 一、MySQL 体系结构&#xff1a; 二、存储引擎概念&#xff1a; MySQL 中的数据用于各种不同的技术存储在文件或内存。这些技术的每一个都使用不同的存储机制、索引技巧、锁定水平&#xff0c;最终提供不同的功能。通过选择不同的技术&#xff0c;能够得到更好的数据处…

03- SVC 支持向量机做人脸识别 (项目三)

数据集描述: sklearn的lfw_people函数在线下载55个外国人图片文件夹数据集来精确实现人脸识别并提取人脸特征向量数据集地址: sklearn.datasets.fetch_lfw_people — scikit-learn 1.2.1 documentationPCA降维: pca PCA(n_components0.9) 数据拆分: X_train, X_test, y_tra…

正大期货本周财经大事抢先看

美国1月CPI、Fed 等央行官员谈话 美国1月超强劲的非农就业人口&#xff0c;让投资人开始上修对这波升息循环利率顶点的预测&#xff0c;也使本周二 (14 日) 的美国 1月 CPI 格外受关注。 介绍正大国际期货主账户对比国内期货的优势 ​第一点&#xff1a;权限都在主账户 例如…

B站基于缓存优化 PRESTO 集群查询性能

导读&#xff1a;本次分享主题为 B 站 Presto 集群查询性能的优化&#xff0c;首先会简单介绍 Presto以及 B 站内部 Presto 集群的架构。接下来讲解针对 Presto 做的改造&#xff0c;主要是 Presto 搭配 Alluxio 和 Presto 搭配 Alluxio local cache 的使用。最后会对后续计划开…

C++类基础(十三)

类的继承 ● 通过类的继承&#xff08;派生&#xff09;来引入“是一个”的关系&#xff08; 17.2 — Basic inheritance in C&#xff09; – 通常采用 public 继承&#xff08; struct V.S. class &#xff09; – 注意&#xff1a;继承部分不是类的声明 – 使用基类的指针…

StarRocks技术内幕 | 资源隔离原理解析

资源隔离一直是 StarRocks 用户讨论较多的话题&#xff0c;对于资源隔离的诉求&#xff0c;主要集中在四点&#xff1a;1. 很多用户关注资源的隔离性&#xff0c;期望当有核心业务的查询运行时&#xff0c;可以限制其他类型任务的使用资源&#xff0c;进而保障核心业务的响应时…

SpringMVC(1)

Web项目:基于HTTP协议&#xff0c;当一个用户从浏览器上面输入URL地址之后&#xff0c;URL能够和我们的程序映射起来&#xff0c;可以让用户的请求触达到后端程序里面&#xff0c;并且根据程序的处理&#xff0c;把结果返回浏览器&#xff1b; Spring MVC要进行学习的内容: 1)连…

三分钟学习 Gitee OpenAPI

文章目录1 什么是 Gitee Open API ?2 如何操作Open API ?2.1 申请私人令牌2.2 发起网络请求3 其他Git Open API3.1 Github Open API3.2 Gitlab OpenAPI1 什么是 Gitee Open API ? 简单说就是 网络请求 Open API 让我们可以通过网络请求的方式对 Git仓库的 分支&#xff0…

LinkedList与链表(数据结构系列5)

目录 前言&#xff1a; 1.链表的概念以及分类 1.1链表的概念 1.2分类 1.2.1单向和双向 1.2.2循环和非循环 1.2.3带头和不带头 2.无头单链表的模拟实现 3.双向链表的模拟实现 4.LinkedList的简单介绍 5.LinkedList的遍历 5.1直接打印 5.2for-each遍历 5.3迭代器遍历…

【Vercel】教你部署imsyy/home个人主页

本篇博客教你如何部署一个自己的个人主页 项目地址&#xff1a;https://github.com/imsyy/home 本文首发于 慕雪的寒舍 1.fork仓库vercel部署 首先我们点击fork&#xff0c;将仓库复刻到自己的账户 随后进入vercel&#xff0c;点击dashboard-add new-project 选择你复刻的仓库…

我的Android开发【分代收集算法】

为什么要采用分代收集算法&#xff1f; 分代的垃圾回收策略&#xff0c;是基于这样⼀个事实&#xff1a;不同的对象的⽣命周期是不⼀样的。因此&#xff0c;不同⽣命周期的对象可以采取不同的收集⽅式&#xff0c;以便提⾼回收效率。在 Java 程序运⾏的过程中&#xff0c;会产…

【大数据基础】vmware+ununtu安装详细过程

环境配置 1. 虚拟机VMware下载与安装 首先安装vmware workstation 密钥直接利用科技生成。 检查vmware是否成功安装 2. VMware安装Ubuntu18.04 LTS 在清华源镜像站找到合适版本的ubuntu 联网安装需要一些时间&#xff0c;大致在一到两个小…

NetSuite Balancing Segment平衡段

春节假期偷了一段时间懒&#xff0c;现在开始工作了。今朝谈一个偏门题目&#xff0c;于未知领域再下一城。说这个题目偏&#xff0c;就要讲讲渊源。话说在Oracle的EBS和Fusion产品中的COA领域有个功能叫做“Balancing Segment”。 问了几位Oracle老炮&#xff0c;也说是对第二…

RDS-MySQL算不算国产数据库及其风险问题

作者&#xff1a;IT圈黎俊杰 笔者在参与国内某大型央企信创替代研究工作中&#xff0c;遇到从各方面传来的“云平台上的RDS就是国产数据库&#xff0c;使用RDS替代原数据库&#xff0c;也是信创替代”的说法&#xff0c;当说的人多了&#xff0c;产生的误导性强了以后&#xff…

Qt OpenGL(三十八)——Qt OpenGL 核心模式-绘制彩色的点

提示:本系列文章的索引目录在下面文章的链接里(点击下面可以跳转查看): Qt OpenGL 核心模式版本文章目录 Qt OpenGL(三十八)——Qt OpenGL 核心模式-绘制彩色的点 一、场景 续接上一篇文章(动态刷新点云),动态刷新点云数据,如下图: 如果,我们需要的点的绘制是彩…

数据挖掘学习笔记——GEO数据库:芯片数据分析

数据挖掘 数据挖掘学习笔记——GEO数据库&#xff1a;芯片数据分析 文章目录数据挖掘一、芯片基础知识1.1、背景二、GEO数据库概述2.1、基础简介2.2、检索页面展示三、GSE项目的三种下载方式3.1、主页下载原始数据3.2、主页下载表达矩阵3.3、GEOquery包下载表达量四、基因名与…

AI与制造的联合与突破,捷配是作何选择的?

最近的chatGPT可谓是火遍全球&#xff0c;人工智能与AI的话题再一次被推上了各大平台热搜&#xff0c;各个行业、各路专家也大谈对各个行业的影响。那么PCB制造业中&#xff0c;AI意味着什么&#xff1f;某一天&#xff0c;在生产工厂中&#xff0c;看着每一条生产链条持续运行…