分书问题(暴搜)

本文介绍了如何使用递归和C++解决一个分书问题,其中涉及二维数组表示人们的阅读兴趣。给定N本书和N个人,目标是找到所有使人人都满意(即拿到自己喜欢的书)的分书方案。样例输入和输出展示了问题的具体实例,代码包括原始递归版本和暴力搜索版本,并提示了剪枝优化的可能性。

分书问题(递归,C++实现)

问题描述
现在有N本书,准备分给N个人。每个人的阅读兴趣,用一个二维数组like[i][j]加以描述。

若 like[i][j] = 1 ,则表示第i个人喜欢第j本书;反之,若 like[i][j] = 0 ,则表示第i个人不喜欢第j本书。

现在已知like数组,请写一个程序,输出所有的分书方案,让人人皆大欢喜。


输入描述
第一行有一个整数N。(N <= 20)

之后有N行,每i行有N个数a_ij,取值为0或1,表示like数组,即第i个人是否喜欢第j本书。0表示不喜欢,1表示喜欢。


输出描述
输出多行。

每行输出一种分书方案,按顺序输出1~N每个书分给对应的人的编号。

所有分书方案,按字典序从小到大的顺序输出。


样例输入

5
0 0 1 1 0
1 1 0 0 1
0 1 1 0 1
0 0 0 1 0
0 1 0 0 1

样例输出

2 3 1 4 5
2 5 1 4 3


问题分析
观察矩阵和输出结果,得知第i行代表具体的书,第j列代表具体的人。如样例输出第一行的解释:

  1. 第二行第1列为1,代表第二本书被分配给第1个人
  2. 同理,第三本书被分配给第2个人
  3. 第一本书被分配给第3个人
  4. 第四本书被分配给第4个人
  5. 第五本书被分配黑第5个人

注意到输出结果有如下性质:

  • 满足条件的元素只能出现位置在二维数组(矩阵)标记为1的位置
  • 在输出时每一行或每一列,有且仅出现1个元素(被分配后就不会再被分配)

因此可将上述性质作为分配时判断的条件(代码第22行)。

在寻找结果中,由于分配的前一项会影响后一项的结果,但寻找过程都是类似的、同性质的问题,所以可利用递归解决该问题。
除矩阵外,因为在递归时需要记录具体的书籍是否被某个人拿过,所以添加记录书籍被取走的数组(assigned)方便判断,并且利用另一个数组记录拿走该书的人员id(数组take)方便输出。


代码

#include <iostream>
using namespace std;

int N = 0;           //共有N个人和N本书
int like[20][20];    //未知二维数组的大小上限为25*25
int num = 0;         //方案数
int take[25];        //分书方案,分给具体某个人
bool assigned[25];   //某本书是否已经分过

void Try(int id) {
	//递归终止条件:
	if (id == N) {
		num++;
		for (int i = 0; i < N; i++)
			cout << take[i]+1 << " ";
		cout << endl;
		return;
	}

	//为每本书找适合的读者:
	for (int i = 0; i < N; i++) {
		if (like[i][id] == true && !assigned[i]) { //第i本书被第id个人喜欢
			//记录分书情况:
			take[id] = i;       //第id本书被第i个人拿了
			assigned[i] = true;

			//为下一本书找合适的读者
			Try(id + 1);

			//将书退还,递归结束后方便下一次寻找
			assigned[i] = false;
		}
	}
}

int main() {
	cin >> N;
	//输入
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++)
			cin >> like[i][j];
	}
	Try(0);   //从第0个人开始尝试

	return 0;
}

—————————————————————————————————
两年后翻写版代码(暴搜)
注:这个版本是方便理解的纯暴力版,如果实际考试的时候出现TLE,需要剪枝优化
代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 25;
int like[N][N];
bool book_st[N], person_st[N];       //某本书已经被拿走了、某个人已经拿到了书
int path[N];                         //用于存储方案数
int n;

int dfs(int u) {   //从第u本书开始枚举
    if(u > n) {
        for(int i = 1; i <= n; i ++) printf("%d ", path[i]);
        puts("");
        return 0;
    }
    
    for(int j = u; j <= n; j ++) {     //先枚举每本书
        for(int i = 1; i <= n; i ++) { //再枚举每个人
            if(like[i][j] && !book_st[j] && !person_st[i]) {
                book_st[j] = true;
                person_st[i] = true;
                path[u] = i;
                
                dfs(u + 1);
                
                path[u] = 0;           //搜状态,要还原现场
                person_st[i] = false;
                book_st[j] = false;
            }
        }
    }
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= n; j ++) scanf("%d", &like[i][j]);
    }
    
    dfs(1);
    
    return 0;
}
<think>嗯,用户之前让我做了一个深度学习学习路径的流程图,分初期、进阶、强化三个阶段,现在他们想要我用小红书爆款博文的形式来介绍各个阶段。首先,我需要理解用户的需求变化。他们可能觉得之前的流程图虽然详细,但不够吸引人,或者想用更贴近大众、更具传播性的方式来呈现内容,适合社交媒体平台,比如小红书。 小红书上的爆款博文通常有几个特点:标题吸引眼球,使用表情符号和分段清晰,语言活泼亲切,多用emoji,内容结构通常是痛点+解决方案,或者步骤式、清单式,配合个人体验和实用建议。所以,我需要把原本的技术性内容转化为更轻松易懂、有亲和力的文案。 接下来,我需要回顾之前的三个阶段内容,将其拆解成适合小红书的格式。初期阶段的关键是基础构建,数学、编程、机器学习基础。这时候的读者可能是刚入门的小白,所以需要强调克服困难的方法和实用资源。进阶阶段是理论与实践结合,重点在神经网络和实战项目,用户可能已经有基础,需要鼓励他们动手做项目。强化阶段是专业深化,涉及高级主题和工程化,适合那些想深入或转行的人,需要突出职业发展和研究方向。 要注意每个阶段的标题要吸引人,比如使用“手把手教你入门”、“从理论到实战”、“进阶大神必备”这样的关键词。内容里要加入痛点,比如“数学劝退?不存在的!”来打消读者顾虑。还要使用表情符号来增加活泼感,比如🚀、💡、🔥等,让内容更生动。 另外,用户可能需要一些互动和鼓励,比如在结尾加上“评论区留言你的学习阶段”来增加互动。资源推荐部分要简洁,用符号分隔,方便读者快速获取信息。标签部分要包含相关话题,比如#深度学习、#AI学习路线,这样有助于内容被更多目标用户发现。 可能用户没明说的需求是希望内容不仅信息量大,还能激励读者,让他们觉得学习路径可行,有明确的步骤和资源支持。所以,在写作时要加入鼓励性的语言,比如“别怕枯燥,基础打牢才能起飞!”、“挑战高薪offer不是梦!”来增强动力。 最后,检查是否符合小红书的风格,确保每部分简短,段落清晰,使用符号和换行来提升可读性。避免技术术语过多,用更口语化的表达,比如“保姆级教程”、“小白也能看懂”来拉近和读者的距离。</think>以下是用 **小红书爆款博文风格** 整理的深度学习三阶段介绍,搭配表情包和互动话术,适合快速传播和种草👇 --- ### **🔥阶段一:小白入门 | 手把手教你从0到1搞懂深度学习!** **适合人群**:完全零基础,数学编程都头秃的萌新 **痛点**: ❌ 一看到“梯度下降”就懵圈? ❌ 代码跑不通,全网找bug到怀疑人生? **保姆级教程**: 1️⃣ **数学劝退?不存在的!** ▫️恶补3大核心:线性代数(矩阵运算)+ 概率统计(贝叶斯公式)+ 微积分(梯度!) ▫️💡隐藏技巧:用《3Blue1Brown》动画课学,直观到跪! 2️⃣ **Python急救包** ▫️速通语法→狂练NumPy/Pandas数据处理 ▫️PyTorch框架抄近路:直接跟官方教程敲代码(GitHub“PyTorch Tutorial”) 3️⃣ **机器学习初体验** ▫️从“线性回归”开始→3天复现房价预测模型 ▫️🚀成就感拉满:Kaggle入门赛(泰坦尼克号生存预测)冲个青铜奖! **📢 互动**: “评论区留言你卡在哪个环节,揪3个宝子送代码debug大礼包!” --- ### **🚀阶段二:进阶突围 | 从调参侠到项目大佬的逆袭!** **适合人群**:会写代码但模型跑分像玄学的新手 **痛点**: ❌ CNN/RNN傻傻分不清? ❌ 调参调到深夜,结果还不如随机数? **逆袭指南**: 1️⃣ **神经网络拆解** ▫️搞懂前向传播+反向传播(链式法则yyds!) ▫️激活函数选ReLU还是Sigmoid?答案藏在损失函数曲线里! 2️⃣ **经典模型复刻** ▫️CNN必玩:用PyTorch实现ResNet,MNIST手写数字识别→秒变朋友圈学霸 ▫️NLP党狂喜:BERT+情感分析实战(某红书爆款评论分类拿来练手!) 3️⃣ **项目镀金法则** ▫️GitHub建仓库→放数据集+代码+README(HR面试直接甩链接!) ▫️💥隐藏加分项:用W&B记录超参数优化过程,可视化界面帅到离谱! **📢 言**: “别怕Kaggle卷不过!跟着TOP方案逐行解读,小白也能冲进前50%!” --- ### **💎阶段三:封神之路 | 挑战AI高薪offer的终极武器!** **适合人群**:想冲大厂/发顶会论文的硬核玩家 **痛点**: ❌ 模型部署一脸懵?工业级项目无从下手? ❌ 论文读不懂,复现结果像开盲盒? **王炸组合**: 1️⃣ **高阶模型实战** ▫️GAN生成二次元老婆(附教程:StyleGAN2+动漫数据集) ▫️强化学习训练AI玩《王者荣耀》(GitHub“王者AI开源项目”) 2️⃣ **工程化秘籍** ▫️模型压缩:知识蒸馏让ResNet瘦身90%! ▫️部署实战:把YOLO检测模型塞进手机(Android Studio+TensorFlow Lite) 3️⃣ **学术/工业二选一** ▫️科研党:精读10篇顶会论文→复现→魔改创新点(CVPR/ICLR冲就完事) ▫️就业党:刷爆LeetCode算法题+开发LLM落地项目(挑战年薪50W+!) **📢 扎心总结**: “发顶会的大佬也曾是调参侠,你和大厂offer的距离,只差一个果断的Star⭐!” --- ### **🌟资源福利区** ``` 【数学基础】《深度学习数学简易入门》电子书👉评论区扣“666” 【代码模板】GAN+Transformer项目合集👉关注后私信“DL”自动发送 【避坑指南】新手必看的10大误区文档👉戳主页群聊领取 ``` **#深度学习 #AI学习路线 #Kaggle竞赛 #转行人工智能 #研究生日常** --- **互动话术**: “你的深度学习修炼到哪个阶段了? A. 刚入坑瑟瑟发抖 B. 调参侠正在渡劫 C. 项目大佬求带飞 评论区蹲校友组队!”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cloud Stream

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值