双向DFS

简介: 复习acwing算法提高课的内容,本篇为讲解算法:双向DFS,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。

文章目录

前言

一、双向DFS

二、AcWing 171. 送礼物

本题解析

AC代码

三、时间复杂度


前言

复习acwing算法提高课的内容,本篇为讲解算法:双向DFS,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。


一、双向DFS

和 双向广搜 原理一样,都是在数据十分庞大的情况下用两端同时搜索的方法去搜索得到最优解,具体原理可见博客:双向广搜


二、AcWing 171. 送礼物

本题链接:AcWing 171. 送礼物

本博客提供本题截图:

image.png

本题解析

用到了二分法,二分法的模板和原理见博客:二分法,我们的思路是让物品一半去打表计算可能的组成的组合,我们是按照正好取半去分两组dfs,其实可以根据分析题意让其中更加复杂的部分减少递归,让简单的部分增加递归,不管是dfs1还是dfs2我们都需要传递两个参数,第一个参数代表当前枚举的是第几个物品,第二个参数代表当前选择的情况下的总重量。weights数组存储的是我们前一半的物品可能组成的重量的集合,因为每个物品都有可能拿或者不拿,所以我们的数组长度为1 << 23,dfs1的作用就是计算出weight,利用剪枝我们知道我们需要从大到小排列weight,因为我们的weight中可能有重复的元素,且我们不需要重复的元素,去除冗余的代码为:

sort(weights, weights + cnt);
cnt = unique(weights, weights + cnt) - weights;

cnt代表的就是去除冗余后数组的长度,同时我们的cnt是从1开始的,因为最初的时候是没有任何重量,且什么物品都不选也是一种重量即0

dfs2的作用就是在后半部分的物品中,利用二分法找到满足s + w[u] <= m的最大s + w[u],并且更新ans

AC代码

#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 46;
int n, m, k;
int w[N];
int weights[1 << 23], cnt = 1;
int ans;
void dfs1(int u, int s)
{
    if (u == k)
    {
        weights[cnt ++ ] = s;
        return;
    }
    dfs1(u + 1, s);      //选择该物品
    if ((LL)s + w[u] <= m) dfs1(u + 1, s + w[u]);  //不选择该物品
}
void dfs2(int u, int s)
{
    if (u >= n)
    {
        int l = 0, r = cnt - 1;
        while (l < r)
        {
            int mid = l + r + 1 >> 1;
            if ((LL)s + weights[mid] <= m) l = mid;
            else r = mid - 1;
        }
        ans = max(ans, s + weights[l]);
        return;
    }
    dfs2(u + 1, s);  //不选当前的物品
    if ((LL)s + w[u] <= m) dfs2(u + 1, s + w[u]); //选当前的物品
}
int main()
{
    cin >> m >> n;
    for (int i = 0; i < n; i ++ ) cin >> w[i];
    sort(w, w + n);
    reverse(w, w + n);
    k = n / 2;
    dfs1(0, 0);
    sort(weights, weights + cnt);
    cnt = unique(weights, weights + cnt) - weights;
    dfs2(k, 0);
    cout << ans << endl;
    return 0;
}

三、时间复杂度

关于双向DFS的时间复杂度以及证明,后续会给出详细的说明以及证明过程,目前先鸽了。


目录
相关文章
|
7月前
|
人工智能 监控 开发者
详解大模型应用可观测全链路
阿里云可观测解决方案从几个方面来尝试帮助使用 QwQ、Deepseek 的 LLM 应用开发者来满足领域化的可观测述求。
1735 157
详解大模型应用可观测全链路
|
算法 安全 网络安全
简单认识一下mbedTLS
简单认识一下mbedTLS
1678 0
|
NoSQL Oracle 关系型数据库
分布式事务Seata【二】CAP定理和Base定理
CAP原则又叫CAP定理,同时又被称作布鲁尔定理(Brewer's theorem)
385 0
分布式事务Seata【二】CAP定理和Base定理
|
9月前
|
存储 安全 大数据
阿里云存储:优缺点深度剖析
阿里云存储是国内领先的云存储服务,具备高效稳定、弹性可扩展、安全可靠及丰富的产品线等优点,适用于各种规模的企业。其分布式架构支持高并发和大数据处理,提供多层次的安全防护和灵活的存储方案。然而,成本较高、数据安全风险和网络连接稳定性等问题也需关注。用户应根据需求权衡利弊,选择合适的存储方案。
982 74
|
7月前
|
存储 运维 BI
万字长文带你深入广告场景Paimon+Flink全链路探索与实践
本文将结合实时、离线数据研发痛点和当下Paimon的特性,以实例呈现低门槛、低成本、分钟级延迟的流批一体化方案,点击文章阅读详细内容~
|
10月前
|
Java Maven
Maven编译报错:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile 解决方案
在执行Maven项目中的`install`命令时,遇到编译插件版本不匹配的错误。具体报错为:`maven-compiler-plugin:3.13.0`要求Maven版本至少为3.6.3。解决方案是将Maven版本升级到3.6.3或降低插件版本。本文详细介绍了如何下载、解压并配置Maven 3.6.3,包括环境变量设置和IDEA中的Maven配置,确保项目顺利编译。
11578 5
Maven编译报错:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile 解决方案
|
Shell Android开发
MT8385 Android AB分区系统升级(命令模式)
MT8385 Android AB分区系统升级(命令模式)
288 0
|
11月前
|
开发者
鸿蒙next版开发:ArkTS组件通用属性(组件标识)
在HarmonyOS 5.0中,ArkTS的组件标识(ID)为每个组件提供唯一标识符,方便开发者引用和操作组件。本文详细解读了id和key属性的使用方法,并提供了示例代码,展示了如何通过组件标识获取属性、发送事件及动态操作组件。
694 1
|
并行计算 PyTorch 算法框架/工具
PyTorch 2.2 中文官方教程(十七)(4)
PyTorch 2.2 中文官方教程(十七)
511 2
PyTorch 2.2 中文官方教程(十七)(4)
|
XML JSON Java
Spring Boot与Solr的集成应用
Spring Boot与Solr的集成应用