深度优先搜索——枚举组合

2023-05-16

所谓枚举组合,其实就是从若干个选若干个数。
比如x[1],x[2],x[3],x[4],……x[n]每个数字时0(不选)和1(选)
x表示当前选到第几个书,dep表示选了几个数
对于每个数来说,它有选或不选两种可能,时间复杂度就是O(2^n)
核心代码:

int n, k;
int comb[N];
void dfs(int x, int dep) {
    if(dep == k) {
        for (int i = 0; i < k; i++) {
          cout << comb[i] << " ";
        }
        cout << endl;
        return;
    }
    if(x > n) {
        return ;
    }
    comb[dep] = x;
    dfs(x + 1, dep + 1);
    dfs(x + 1, dep);
}

找出从自然数 1、2……n(0<n<10)中任取 r(0<r≤n) 个数的所有组合。
输入格式
输入 n、r。
输出格式
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。

先考虑如果不按特定舒徐输出的程序应该是:
示例代码

#include <iostream>
using namespace std;
const int N = 15;
int n, k;
int comb[N];
void dfs(int x, int dep) {
    if(dep==k){
        for(int i=0;i<k;i++){
            cout<<comb[i];
        }
        cout<<endl;
        return;
    }
    if(x>n)
        return;
    comb[dep]=x;
    dfs(x+1,dep+1);
    dfs(x+1,dep);
}

int main()
{
    cin >> n >> k;
	dfs(1, 0);
    return 0;
}

但题目中要求按照字典序逆序排列,而现在是按照字典序排列,所以就应该是在找x的时候倒着找就可以了。
示例代码:

#include <iostream>
using namespace std;
const int N = 15;
int n, k;
int comb[N];
void dfs(int x, int dep) {
    if(dep==k){
        for(int i=0;i<k;i++){
            cout<<comb[i];
        }
        cout<<endl;
        return;
    }
    if(x<=0)
        return;
    comb[dep]=x;
    dfs(x-1,dep+1);
    dfs(x-1,dep);
}

int main()
{
    cin >> n >> k;
	dfs(n, 0);
    return 0;
}

这道题的中重点就是倒序,而倒序的重点就是为什么一i开始写的是正序。 ·

蒜头君来到文具店,选择了 k 支自己喜欢的水彩笔,并抄下了它们的价格。可是到结算时,他发现自己抄价格时抄得太密集,以至于所有价格连成了一个数字串。老板想和蒜头君开个玩笑,于是对他说:“你可以把这个数字串分成 k 段,代表这 k 支笔的价格,然后把他们加起来,就是你要付给我的钱了。”

当然,蒜头君想尽可能省下钱去买《算法导论》,所以请你来帮忙算算,他最少需要付多少钱。注意水彩笔的钱可以为 0 元。

数据范围:1≤k≤∣s∣≤8,s 仅包含数字 0∼9。

样例输入
72553
3
样例输出
85
先分析一下样例,就应该是7+25+53=85
现在来将一个比较奇特的思路,dfs过程中我们记录4个信息,dfs(int u,int x,int sum,int cnt)u表示现在枚举到第几位(字符串下表),x是现在枚举的价钱,sum是总价,cnt表示现在枚举了几根笔(段数)。
当前第u位有两种可能

  1. 跟前面的合并
  2. 独立的新数字
    1的情况就是x变更为now10+s[u],sum不变
    2的情况就是x变更为0,sum变为sum+10
    x+s[u]
#include<iostream>
#include<cstring>
using namespace std;
int n,k,a[1005],ans=1e9,nownum;
string s;
void dfs(int u,int x,int sum,int cnt){
/*u表示处理到的数字
x表示由之前部分带来的数字
sum表示当前的数字
cnt表示已经选取了几个数字
当cnt=k且u=n时完事*/
if(u==n){
	if(cnt==0){
		ans=min(ans,sum+x);
	}
	return;
}
if(cnt<0)
	return;
dfs(u+1,x*10+a[u],sum,cnt);
dfs(u+1,0,sum+10*x+a[u],cnt-1);

}
int main(){
	cin>>s>>k;
	n=s.size();
	for(int i=0;i<n;i++)
		a[i]=(int)s[i]-'0';
	dfs(0,0,0,k-1);
	cout<<ans;
	return 0;
}

超级书架2:
展开
题目描述
Farmer John最近为奶牛们的图书馆添置了一个巨大的书架,尽管它是如此的大,但它还是几乎瞬间就被各种各样的书塞满了。现在,只有书架的顶上还留有一点空间。 所有N(1 <= N <= 20)头奶牛都有一个确定的身高H_i(1 <= H_i <= 1,000,000 - 好高的奶牛>_<)。设所有奶牛身高的和为S。书架的 高度为B,并且保证1 <= B <= S。 为了够到比最高的那头奶牛还要高的书架顶,奶牛们不得不象演杂技一般,一头站在另一头的背上,叠成一座“奶牛塔”。当然,这个塔的高度,就是塔中所有奶牛的身高之和。为了往书架顶上放东西,所有奶牛的身高和必须不小于书架的高度。 塔叠得越高便越不稳定,于是奶牛们希望找到一种方案,使得叠出的塔在高度不小于书架高度的情况下,高度尽可能小。你也可以猜到你的任务了:写一个程序,计算奶牛们叠成的塔在满足要求的情况下,最少要比书架高多少。

输入格式

  • 第1行: 2个用空格隔开的整数:N 和 B
  • 第2…N+1行: 第i+1行是1个整数:H[i]

输出格式

  • 第1行: 输出1个非负整数,即奶牛们叠成的塔最少比书架高的高度

输入输出样例
输入 #1
5 16
3
1
3
5
6
输出 #1
1
说明/提示
输出说明:

我们选用奶牛1、3、4、5叠成塔,她们的总高度为3 + 3 + 5 + 6 = 17。任何方案都无法叠出高度为16的塔,于是答案为1。

dfs(int i,int s)状态表示现在第i位数字选还是不选,s表示当前的总和,这道题只需要输出有几种方案,而不用输出每种方案,这使得代码变得简单了许多
可以把这个看作一个搜索树
在这里插入图片描述

#include<iostream>
using namespace std;
int n,high,a[25],ans=1e9;
void dfs(int u,int hight){
	if(u==n+1){
		//cout<<hight<<" ";
		if(hight>=high){
			ans=min(ans,hight-high);
		}
		return;
	}
	dfs(u+1,hight+a[u]);
	dfs(u+1,hight);
}
int main(){
	cin>>n>>high;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	dfs(1,0);
	cout<<ans;
	return 0;
}

这道题目其实也可以用状压dp或背包啥的,但是这道题给的数字数量比较小,所以就没有必要了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度优先搜索——枚举组合 的相关文章

  • 安装卸载EMBY,jellyfin

    这是个回忆记录 xff0c 怕时间久了忘记了 xff0c 记录可能不太全 环境是 xff1a UNAS xff0c debian xff0c 1 安装emby xff0c 去官网下载emby deb 用命名安装 安装后访问正常 卸载就麻烦了
  • centos8 OPEN LDAP部署

    英文安装文档 比较清晰 xff0c 不过为了以防万一还是记录一下 1 安装 openldap openldap servers root 64 yl08 tools yum install openldap openldap servers
  • [CentOS入门](一)Linux基础

    登陆系统方式 xff1a 文本登陆图形登陆远程登陆 终端的使用方式 xff1a centos有5个虚拟文本终端 xff0c 1个图形终端 tty 命令查看当前虚拟终端 系统支持多用户 xff08 包括使用相同用户 xff09 同时登录系统
  • [Linux]LVM (Linux 逻辑卷管理)

    概念 xff1a LVM是 Logical Volume Manager xff08 逻辑卷管理 xff09 的简写 xff0c 它是Linux环境下对磁盘分区进行管理的一种机制 PV xff1a 硬盘和分区都可以标记为PV xff0c P
  • [CentOS入门](二)Linux Bash

    Bash命令 xff1a Shell是用户与操作系统交互的入口 xff0c Bash是最常用的Linux Shell Bash命令格式 xff1a 命令 选项 参数 中间用空格分隔 命令选项参数ls lh var 如果参数中包含空格则需要在
  • 逻辑回归(LogisticRegression)算法及简单案例

    逻辑回归 LogisticRegression 算法及简单案例 大家好 xff0c 我是W 逻辑回归虽然名字有回归 xff0c 但是实际上是分类模型 xff0c 常用于二分类 回归的意思是 xff1a 在二维空间中找到一条最佳拟合直线去拟合
  • [CentOS入门](三)文件系统

    Linux文件系统结构树 xff1a 目录中颜色的含义 xff1a 青色 xff1a 指向另外一个位置 xff0c 软连接 ls显示文件夹中的文件链接指向位置 xff1a ls folder l蓝色 xff1a 一个文件夹绿色 xff1a
  • [CentOS入门](四)编辑器

    vim xff1a vi vim是一种Linux自带的文本编辑器 xff0c 也是常用的文本编辑器之一 xff0c vim相对于vi增加了代码颜色等功能 部分Linux最小化安装时会预装vi xff0c 但不包含vim xff0c 手动安装

随机推荐

  • [CentOS入门](五)系统软件管理

    RPM RPM是由红帽开发 xff0c 用于管理软件包的组件 xff0c 但是其原始设计理念是开放式的 xff0c 包括OpenLinux S u S E 以及Turbo Linux等Linux的分发版本都有采用 rpm是软件的最小单位 r
  • [CentOS入门](六)用户、组、权限

    用户 xff1a 用户ID为0的用户为超级用户 xff0c 0 500之间为系统级用户 xff0c 为服务保留 xff0c 通常情况新建的用户UID gt 500 用户文件保存在 etc passwd文件中 组 xff1a 每个用户有一个私
  • Traccar记录足迹-服务搭建及使用

    Traccar介绍 Traccar是一款开源的可以跟踪GPS设备位置的应用 xff0c 服务端支持Windows x64 Linux x64 Linux ARM 客户端支持GPS设备 Android设备 IOS设备 搭建Traccar服务器
  • [网络]OSPF理论

    特性 xff1a 分类 xff1a 无类 xff0c 链路状态协议封装 xff1a ip xff08 89 xff09 更新目标地址 xff1a 224 0 0 5 224 0 0 6 支持单播更新方式 xff1a 定时 完整定时更新 xf
  • [网络]IPV6

    IPV6优势 xff1a 更大地址空间 xff08 2 128 xff09 端到端的全球可达性层次化编址利于聚合 xff08 每个运营商一个地址块 xff09 组播的使用 xff08 Server传播一份流量 xff0c 通过组播扩散到用户
  • Proxmox VE(PVE)+ceph+物理网络规划-超融合生产环境安装部署案例

    1 Proxmox Virtual Environment介绍 Proxmox VE 是用于企业虚拟化的开源服务器管理平台 它在单个平台上紧密集成了KVM虚拟机管理程序和LXC xff0c 软件定义的存储以及网络功能 借助基于Web的集成用
  • [XPlane11/12]同步更新Zibo737插件下载-更新至3.54.17-插件搬运

    Boeing B737 800X mod 链接中包括XPlane11和XPlane12版 XPlane11版本已更新至3 54 17 xff1b XPlane12版本已更新至2 1 一 下载链接 xff1a 捐助ZIBOmod xff1a
  • Proxmox VE(PVE)备份组件:PBS(Proxmox Backup Server)部署及使用教程

    1 Proxmox Backup Server xff08 pbs xff09 介绍 Proxmox Backup Server xff08 pbs xff09 是与pve配套的备份解决方案 xff0c 用于备份和恢复虚拟机 容器和物理主机
  • maven mirror

    lt mirror gt lt id gt UK lt id gt lt name gt UK Central lt name gt lt url gt http uk maven org maven2 lt url gt lt mirro
  • 1002 A+B for Polynomials (25分)

    题目大意 输入两行 xff0c 每行格式如上 xff0c K为多项式中非零项的个数 xff0c N为指数 xff0c aN为该项的系数 最后输出两个多项式的和 思路 xff1a 用一个结构体数组 ploy xff0c 数组中的每个元素存储该
  • linux/unix 使用airport

    把airport引入到用户命令里 xff0c 建立一个软连接 span class hljs built in sudo span ln span class hljs operator s span System Library Priv
  • 网页中提取SWF游戏文件及运行修改

    1 下载游戏到本地 以4399游戏为例 首先需要找到游戏页面如下 xff1a
  • k8s快速部署,附带脚本

    内容导航 xff08 一 xff09 资产信息 xff08 二 xff09 脚本内容 xff08 三 xff09 网络插件flannel1 xff0c 使用flannel网络插件2 xff0c 修改网络模式为ipvs xff0c svc无法
  • pandas处理大文件

    目录 思路一 xff1a 分而治之 思路二 xff1a 精简数据 demo 思路一 xff1a 分而治之 分而治之 xff0c 分批次加载大文件 xff0c 每次读取一定行数的数据 xff0c 读一批处理一批 此方法简单有效 xff0c 易
  • C++详解:枚举类型 --- enum | Xunlan_blog

    文章目录 一 概念二 定义枚举元素表 三 定义枚举对象的操作 四 要点 amp 技巧实例 一 概念 枚举类型 enumeration xff0c 是C 43 43 中的一种派生数据类型 xff0c 是用户创建的一个集合 xff0c 可以增加
  • 使用vue3+axios和后端交互时无法改变的data中的数据

    今天在编写前端页面的时候 xff0c 打算引入axios进行ajax请求 xff0c 可以在这个过程中遇到了一个非常大的坑 xff0c 先来看看有坑的代码 我们看一下浏览器端的console的打印情况 可以看到 xff0c 第二次打印thi
  • Ubuntu20.04搜狗输入法官方安装指南实操

    前言 linux下也想用已经熟悉的搜狗输入法 xff0c 于是乎 xff0c 在网上查各种教程 xff0c 发现很多都不能成功 xff0c 在要放弃的时候 xff0c 下面这个链接帮助自己完成了这个任务 xff1a 官方教程 xff1a U
  • 国王游戏——c++实现

    题目描述 恰逢 H 国国庆 国王邀请 n 位大臣来玩一个有奖游戏 首先 他让每个大臣在左 右手上面分别写下一个整数 xff0c 国王自己也在左 右手上各写一个整数 然后 xff0c 让这 n 位大臣排成一排 xff0c 国王站在队伍的最前面
  • 正确打开db文件的方式,避免乱码和无意义内容

    db文件如果用记事本或者Notepad 43 43 打开 xff0c 会显示乱码 xff0c 改变编码不能解决问题 xff0c 如果用UltraEdit打开 xff0c 可以看到进制数据 xff0c 但是无意义的 正确的方法有多种 xff1
  • 深度优先搜索——枚举组合

    所谓枚举组合 xff0c 其实就是从若干个选若干个数 比如x 1 x 2 x 3 x 4 x n 每个数字时0 xff08 不选 xff09 和1 xff08 选 xff09 x表示当前选到第几个书 xff0c dep表示选了几个数 对于每