【dfs解决分组问题-两道例题——供佬学会!】(A元素是放在已经存在的组别中,还是再创建一个更好?--小孩子才做选择,dfs直接两种情况都试试)

news2024/11/23 18:46:13

问题关键就是:
一个点,可能
新开一个组

放到已经存在的组
更划算
因为后面的数据,我们遍历之前的点时,并不知道

所以我们应该针对每个点,都应该做出一个选择就是
新开一个元组或者放到之前的元组中,都尝试一次
(截取重点内容,继续往下看)

我们发现这道题目有两个可以剪枝的部分,
一个是如果当前的答案已经大于了我们已知的最小答案,不用说直接return返回即可.
第二个剪枝则是,我们可以将小猫的体重从大到小排序,这样我们的搜索树就会缩短许多,至于为什么,因为我们的剩余空间就变小了,然后可选择的猫也就少了

(截取重点内容,继续往下看)

欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)
 
文章字体风格:
红色文字表示:重难点★✔
蓝色文字表示:思路以及想法★✔
 
如果大家觉得有帮助的话,感谢大家帮忙
点赞!收藏!转发!

dfs解决分组问题

    • 分成互质组
        • 错误想法:从头遍历,如果不匹配,则开新组
        • 正确想法:小孩子才做选择,dfs直接两种情况都试试
    • 小猫爬山
        • 减枝思想!!!

分成互质组

在这里插入图片描述
首先什么是互质?

互质就是 彼此的最大公约数是 1

求a,b的最大公约数

int gcd(int a,int b)
{
    while(b)
    {
        int c = a % b;
        a = b;
        b = c;
    }
    return a;
}

错误想法:从头遍历,如果不匹配,则开新组

本题,我的想法是:
从头遍历,如果不匹配,则开新组

用样例说就是

6
14 20 33 117 143 175

选择20看之前已经开辟的 组别

如果已经存在的 组别中的元素
和当前的不符合,那么换另一个组别再次尝试
如果都不合适,那么直接创建新组
错误代码
#include<iostream>
#include<vector>

using namespace std;

const int N = 11;

int n;
int a[N];
vector<int> g[N];

int gcd(int a,int b)
{
    while(b)
    {
        int c = a % b;
        a = b;
        b = c;
    }
    return a;
}
int g_size;
void dfs(int u)
{
    if(u>n)
        return;
    for(int i = 1; i <= g_size; i++)
    {
        int flag = 1;
        for(int j = 0; j < g[i].size(); j++)
        {
            if(gcd(a[u],g[i][j])!=1)
            {
                flag = 0;
            }
        }
        if(flag==1)
        {
            // cout << a[u] << ' ';
            g[i].push_back(a[u]);
            dfs(u+1);
            return;
        }
    }
    g_size+=1;
    g[g_size].push_back(a[u]);
    dfs(u+1);
    return;
}

int main()
{
    cin >> n;
    
    for(int i = 1; i <= n; i++)
        cin >> a[i];
        
        
    dfs(1);

    cout << g_size << endl;
    
    return 0;
}

正确想法:小孩子才做选择,dfs直接两种情况都试试

但是出现问题了

4
3 7 6 14

这个样例 安上述思想 分组
3 7
6
14

分出3个组
但是

如果按着 正常分组
应该是 
3
7 6 14
这样更好

问题关键就是:
一个点,可能
新开一个组

放到已经存在的组
更划算
因为后面的数据,我们遍历之前的点时,并不知道
所以我们应该针对每个点,都应该做出一个选择就是
新开一个元组或者放到之前的元组中,都尝试一次

//正确代码
#include<iostream>
#include<vector>

using namespace std;

const int N = 11;

int n;
int a[N];


int gcd(int a,int b)
{
    while(b)
    {
        int c = a % b;
        a = b;
        b = c;
    }
    return a;
}
int ans = 0x3f3f3f3f;
void dfs(int g_size,vector<int> g[N],int u)
{
    if(u>n)
    {
        ans = min(g_size,ans);
        return;
    }
    for(int i = 1; i <= g_size; i++)
    {
        int flag = 1;
        for(int j = 0; j < g[i].size(); j++)
        {
            if(gcd(a[u],g[i][j])!=1)
            {
                flag = 0;
            }
        }
        if(flag==1)
        {
            // cout << a[u] << ' ';
            g[i].push_back(a[u]);
            dfs(g_size,g,u+1);
            g[i].pop_back();
        }
    }
    g[g_size+1].push_back(a[u]);
    dfs(g_size+1,g,u+1);
    g[g_size+1].pop_back();
}

int main()
{
    cin >> n;
    
    for(int i = 1; i <= n; i++)
        cin >> a[i];
        
    vector<int> g[N];
    dfs(0,g,1);

    cout << ans << endl;
    
    return 0;
}

小猫爬山

在这里插入图片描述

减枝思想!!!

本题思路和上题一样,
但关键一点是,咱们可以借助本题,学会剪枝思想

  1. 当我们按某一种方案遍历过程时,发现走到一半发现这个方案,走到了一半已经比我之前走过的方案更费时费力,那么就直接不走这个方案了,减枝

  2. 或者走的过程中,按着从大到小 或者从小到大走,这样说不定也会省时省力,也是减枝

  3. 或者就是我们知道了可实现的最坏情况
    那么超过可实现的最坏情况,一定是不对的,直接不需要继续dfs了,也是剪枝

我们发现这道题目有两个可以剪枝的部分,
一个是如果当前的答案已经大于了我们已知的最小答案,不用说直接return返回即可.
第二个剪枝则是,我们可以将小猫的体重从大到小排序,这样我们的搜索树就会缩短许多,至于为什么,因为我们的剩余空间就变小了,然后可选择的猫也就少了

/*
 * Project: 0x22_深度优先搜索
 * File Created:Sunday, January 24th 2021, 11:31:12 am
 * Author: Bug-Free
 * Problem:AcWing 165. 小猫爬山
 */
#include <algorithm>
#include <iostream>

using namespace std;

const int N = 2e1;

int cat[N], cab[N];
int n, w;
int ans;

bool cmp(int a, int b) {
    return a > b;
}

void dfs(int now, int cnt) {
    if (cnt >= ans) {
        return;
    }
    if (now == n + 1) {
        ans = min(ans, cnt);
        return;
    }
    //尝试分配到已经租用的缆车上
    for (int i = 1; i <= cnt; i++) {  //分配到已租用缆车
        if (cab[i] + cat[now] <= w) {
            cab[i] += cat[now];
            dfs(now + 1, cnt);
            cab[i] -= cat[now];  //还原
        }
    }

    // 新开一辆缆车
    cab[cnt + 1] = cat[now];
    dfs(now + 1, cnt + 1);
    cab[cnt + 1] = 0;
}

int main() {
    cin >> n >> w;
    for (int i = 1; i <= n; i++) {
        cin >> cat[i];
    }

    sort(cat + 1, cat + 1 + n, cmp);
    ans = n;
    dfs(1, 0);

    cout << ans << endl;

    return 0;
}

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

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

相关文章

SolVES 模型生态系统服务功能社会价值评估(基于多源环境QGIS、PostgreSQL、ArcGIS、Maxent、R语言)

查看原文>>>SolVES 模型生态系统服务功能社会价值评估&#xff08;基于多源环境QGIS、PostgreSQL、ArcGIS、Maxent、R语言&#xff09; 目录 第一章、理论基础与研究热点 第二章、SolVES 4.0 模型运行环境配置 第三章、SolVES 4.0 模型运行 第四章、数据获取与入…

简答题题集

简答题&#xff1a; 1.测试和开发如何配合工作&#xff0c;即测试何时介入测试工作&#xff1f; 测试工作应该覆盖需求分析、概要设计、详细设计、编码等前期阶段&#xff0c;而不应该在系统开发初步完成后才开始。 2.软件测试的对象&#xff1a;正确的依据应该是需求规格说明书…

【Java基础篇】数据类型与变量

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a;Java.SE&#xff0c;本专栏主要讲解运算符&#xff0c;程序逻辑控制&#xff0c;方法的使用&…

SRC漏洞挖掘

SRC目标搜集 文章类的平台 国内漏洞响应平台&#xff08;SRC&#xff09;导航 - 安全客&#xff0c;安全资讯平台 百度搜索 首先得知道SRC厂商的关键字&#xff0c;利用脚本搜集一波。 比如【应急响应中心】就可以作为一个关键字。通过搜索引擎搜索一波&#xff0c;去重&…

【LeetCode: 343. 整数拆分 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

前端三剑客

一.前端是什么&#xff1a; 前端主要是考虑怎样能让用户觉得用起来更舒服&#xff0c;考虑界面布局、交互效果、页面加载速度等等&#xff0c;主要是偏向用户看得见的部分&#xff0c;客户端&#xff08;pc、手机、pad&#xff09;上浏览web。网站的“前端”是与用户直接交互的…

自定义表头之数据库设计

数据库设计实现自定义列 表设计如下&#xff1a; 1.数据表 — 就是excel所有列数据的表 字段&#xff1a;&#xff08;这个表根据你所需要的数据列写就可以&#xff09; 案例&#xff1a; 2.列表 — 就是记录每个excel对应的完整列名 字段&#xff1a;&#xff08;我这边是…

Python语法装饰器

参考&#xff1a; 【【python】装饰器超详细教学&#xff0c;用尽毕生所学给你解释清楚&#xff0c;以后再也不迷茫了&#xff01;-哔哩哔哩】 https://b23.tv/Y6Ss8cN【Python小技巧&#xff1a;装饰器(Decorator)-哔哩哔哩】 https://b23.tv/hacMmem x.1 Python中的Abstract…

探索云原生技术的优势和挑战

文章目录 探索云原生技术的优势和挑战一、云原生技术简介二、云原生技术的优势1. 弹性和可伸缩性2. 高可用性3. 快速迭代和部署4. 更好的安全性和可靠性 三、云原生技术的挑战1. 复杂性2. 安全风险3. 成本 四、总结 结语 探索云原生技术的优势和挑战 随着云计算技术的快速发展…

数字城市发展下的技术趋势,你知道多少?

提到数字城市、智慧城市大家都会感觉经常在耳边听到&#xff0c;但是要确切说出具体的概念还是有一点难度的。具体来说&#xff1a;数字城市是一个集合多种技术的系统&#xff0c;以计算机技术、多媒体技术和大规模存储技术为基础&#xff0c;以宽带网络为纽带&#xff0c;运用…

【JavaScript】ES6新特性(2)

5. 字符串扩展 5.1 includes函数 判断字符串中是否存在指定字符 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name&q…

2023年湖北安全员C证C3学历不够可以报考吗 ?个人如何报考?

2023年湖北安全员C证C3学历不够可以报考吗 &#xff1f;个人如何报考&#xff1f; 2023年建筑施工企业三类人员住建厅安全员C证报考是有一定要求的&#xff0c;很多人条件达不到是不是就不能报考&#xff0c;个人想要报考建筑安全员C证怎么去报名等一系列问题。其实都是可以解决…

云渲染与本地渲染:哪个最好?

我们过去曾指出&#xff0c;本地渲染动画和电影的 2D 或 3D 项目是一个非常耗时且计算密集型的过程。当在场景中使用未优化的几何体或在最终渲染中使用多多边形模型时&#xff0c;诸如此类的变量最终将增加完成单个渲染所需的时间和处理器能力。 为什么渲染需要这么长时间&…

keepalived搭建配置

首先&#xff0c;在搞keepalived的时候&#xff0c;一般都是一主一备&#xff0c;所以需要2台设备。这两台设备&#xff0c;要一致&#xff0c;我之前是用了一台centos&#xff0c;一台ubuntu&#xff0c;然后&#xff0c;搞完以后发现&#xff0c;不管是主还是备都持有vip&…

108.(cesium篇)cesium初始定位动画

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <html lang="en"> <

大学生社团管理系统的设计与实现(论文+源码)_kaic

在网络迅速发展的时代&#xff0c;众多软件被开发出来&#xff0c;给社团的管理带了极大的便利&#xff0c;而学生随着时代的发展越来越最求更加个性化的需求。以此&#xff0c;现在的社团管理以学生为导向&#xff0c;根据学生的需求开发一个适合现代化的大学生社团管理系统&a…

Pytest技巧大揭秘:编写高质量接口自动化测试

目录 前言&#xff1a; 一、Pytest测试框架简介 二、安装Pytest测试框架 三、编写Pytest测试用例 四、Pytest参数化&#xff08;Parameterization&#xff09; 五、Pytest插件的使用 六、总结 前言&#xff1a; 在软件开发中&#xff0c;接口的测试是非常重要的一环。接…

Linux服务器安装MYSQL

安装MYSQL 涉及到的工具及软件连接 链接&#xff1a;https://pan.baidu.com/s/1r577kFeuojUrMoEUn88B8w 提取码&#xff1a;xh93 查看是否已经安装了mariadb 检查linux是否安装了mariadb数据库&#xff0c;mariadb数据库是mysql的分支。是免费开源的。mariadb和msyql会有冲突…

准备半个月,面试5分钟不到就凉了,问的实在太····

从外包出来&#xff0c;没想到竟然死在了另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以我也就忍了。没想到12月一纸通知&#xff0c;所有人都不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个…

django ORM框架(操作数据库)第一章

目录 一、ORM框架介绍 二、Django配置数据库 2.1 在本地mysql中创建数据库与用户 2.2 django 连接本地mysql(安装mysqlclient及依赖环境&#xff09;mac安装 三、模型类 3.1、创建模型类&生成迁移脚本&执行迁移脚本 3.2 类属性&表字段介绍 3.2.1 models.Ch…