【剪枝】【广度优先】【深度优先】488祖玛游戏

作者推荐

【动态规划】458:可怜的小猪

涉及知识点

剪枝 广度优先 深度优先

488祖玛游戏

在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 ‘R’、黄色 ‘Y’、蓝色 ‘B’、绿色 ‘G’ 或白色 ‘W’ 。你的手中也有一些彩球。
你的目标是 清空 桌面上所有的球。每一回合:
从你手上的彩球中选出 任意一颗 ,然后将其插入桌面上那一排球中:两球之间或这一排球的任一端。
接着,如果有出现 三个或者三个以上 且 颜色相同 的球相连的话,就把它们移除掉。
如果这种移除操作同样导致出现三个或者三个以上且颜色相同的球相连,则可以继续移除这些球,直到不再满足移除条件。
如果桌面上所有球都被移除,则认为你赢得本场游戏。
重复这个过程,直到你赢了游戏或者手中没有更多的球。
给你一个字符串 board ,表示桌面上最开始的那排球。另给你一个字符串 hand ,表示手里的彩球。请你按上述操作步骤移除掉桌上所有球,计算并返回所需的 最少 球数。如果不能移除桌上所有的球,返回 -1 。
示例 1:
输入:board = “WRRBBW”, hand = “RB”
输出:-1
解释:无法移除桌面上的所有球。可以得到的最好局面是:

  • 插入一个 ‘R’ ,使桌面变为 WRRRBBW 。WRRRBBW -> WBBW
  • 插入一个 ‘B’ ,使桌面变为 WBBBW 。WBBBW -> WW
    桌面上还剩着球,没有其他球可以插入。
    示例 2:
    输入:board = “WWRRBBWW”, hand = “WRBRW”
    输出:2
    解释:要想清空桌面上的球,可以按下述步骤:
  • 插入一个 ‘R’ ,使桌面变为 WWRRRBBWW 。WWRRRBBWW -> WWBBWW
  • 插入一个 ‘B’ ,使桌面变为 WWBBBWW 。WWBBBWW -> WWWW -> empty
    只需从手中出 2 个球就可以清空桌面。
    示例 3:
    输入:board = “G”, hand = “GGGGG”
    输出:2
    解释:要想清空桌面上的球,可以按下述步骤:
  • 插入一个 ‘G’ ,使桌面变为 GG 。
  • 插入一个 ‘G’ ,使桌面变为 GGG 。GGG -> empty
    只需从手中出 2 个球就可以清空桌面。
    示例 4:
    输入:board = “RBYYBBRRB”, hand = “YRBGB”
    输出:3
    解释:要想清空桌面上的球,可以按下述步骤:
  • 插入一个 ‘Y’ ,使桌面变为 RBYYYBBRRB 。RBYYYBBRRB -> RBBBRRB -> RRRB -> B
  • 插入一个 ‘B’ ,使桌面变为 BB 。
  • 插入一个 ‘B’ ,使桌面变为 BBB 。BBB -> empty
    只需从手中出 3 个球就可以清空桌面。

提示:
1 <= board.length <= 16
1 <= hand.length <= 5
board 和 hand 由字符 ‘R’、‘Y’、‘B’、‘G’ 和 ‘W’ 组成
桌面上一开始的球中,不会有三个及三个以上颜色相同且连着的球

剪枝

剪枝一:如果手中有多个相同颜色的球,只需要尝试一个,其它不需要尝试。
剪枝二:如果收中的球和桌面颜色相同的球,只需要考虑插入到最前面。在一个红球的前面或后面插入红球,结果一样两个连续的红球。在两个红球的前面或后面或中间插入红球的效果一样,连续的3个红球消除。
假定插入的颜色是ch,插入的位置是i,只需要考虑以下两种情况:
一,board[i]等于ch。
二,board[i-1]等于board[i]。
忽略剪枝后,再考虑这两种情况。这两种情况都是必须,缺少情况一,无法消除任何球。缺少情况二,无法消除以下用例:
RRWWRRBBRR WB,第一步消除W或B的连锁反应都会消除4个R,造成余下的2个R,无法消除。
RRWWRRBBRWR − − − > 消除 B _{--->}^{消除B} −−−>消除B RRWWRRRWR − − − − − − − − > 连锁消除 3 个 R _{-------->}^{连锁消除3个R} −−−−−−−−>连锁消除3R RRWWWR − − − − − − − − > 连锁消除 3 个 W _{-------->}^{连锁消除3个W} −−−−−−−−>连锁消除3W RRR − − − − − − − − > 连锁消除 3 个 W _{-------->}^{连锁消除3个W} −−−−−−−−>连锁消除3W 结束。

下面来证明为什么只需要考虑两种情况:

0==i两种相等情况一
两种不等假定ch能被消除,假定和ch同时消除,从左向右第一个小标为i1,board[0]和board[i1]一起被消除,说明board(0,i1)能被消除且不依赖不影响board[i1],那将ch不插入到0,插入到i1,操作顺序完全一样。被淘汰。简称证明一。
board.length-1 == i两者相等就是剪枝二。
两者不等类似证明一。
i是中间的下标三者相等剪枝二淘汰。
ch==board[i]就是情况一。
ch==board[i-1]就是剪枝二,淘汰。
board[i-1]==board[i]就是情况二。
三者不等。假定ch能被消除,否则则组合没有任何意义。一个ch无法消除,所以它的左边或边有必定有一个ch被一起消除。不失一般性,假定在它的左边,下标为i1,borad[i1]和ch一起被消除,说明(i1,i)的字符都消除。那将ch插入到i1和i的效果一样。由于board[i-1]不等于board[i]和ch,所以无论是否插入ch,都不会影响右边的字符。 两中方案(i1,i)的左边都是ch,所以新方案不会有影响左边。

第一版代码

class Solution {
public:
int findMinStep(string board, string hand) {
sort(hand.begin(), hand.end());
queue<pair<string, string>> que;
unordered_set setHasDo;
auto Add = [&](const string& s, const string& h)
{
bool bEmpty = s.empty();
const string cur = s + “-” + h;
if (setHasDo.count(cur))
{
return;
}
setHasDo.emplace(cur);
que.emplace(s, h);
};
Add(board, hand);
while (que.size())
{
auto [s, h] = que.front();
que.pop();
if (s.empty())
{
return hand.length() - h.length();
}
unordered_map<char, int> mCharCount;
for (const auto& ch : h)
{
mCharCount[ch]++;
}
for (int j = 0; j < s.length(); j++)
{
if ((j + 1 < s.length()) && (s[j] == s[j + 1]))
{
if (mCharCount.count(s[j]) && (mCharCount[s[j]] >= 1))
{
mCharCount[s[j]]–;
Add(Do(s.substr(0,j+1)+s[j] + s.substr(j+1)),ToString(mCharCount));
mCharCount[s[j]]++;
}
for ( auto& [ch, iCnt] : mCharCount)
{
if (ch != s[j])
{
iCnt–;
Add(Do(s.substr(0, j+1) + ch + s.substr(j + 1)), ToString(mCharCount));
iCnt++;
}
}
}
else
{
if (mCharCount.count(s[j]) && (mCharCount[s[j]] >= 2))
{
mCharCount[s[j]] -= 2;
Add(Do(s.substr(0, j) + s[j] + s[j] + s.substr(j)), ToString(mCharCount));
mCharCount[s[j]] += 2;
}
}
}
}
return -1;
}
string Do(const string& s)
{
stack<pair<char, int>> sta;
for (const char& ch : s )
{
while (sta.size() && (sta.top().first != ch) && (sta.top().second >= 3))
{
sta.pop();
}
if (sta.size() && (sta.top().first == ch))
{
sta.top().second++;
}
else
{
sta.emplace(ch, 1);
}
}
string sRet;
while (sta.size())
{
const auto [ch, iCnt] = sta.top();
sta.pop();
if (iCnt < 3)
{//最后一个元素需要判断
sRet += string(iCnt, ch);
}
}
return sRet; //正序和反序是一样的
}
string ToString(const unordered_map<char, int>& mCharCount)
{
string strRet;
for (const auto& [ch, iCnt] : mCharCount)
{
strRet += string(iCnt, ch);
}
return strRet;
}
}; ,

测试用例

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		Assert(v1[i], v2[i]);
	}
}


int main()
{
	string board,  hand;	
	{
		Solution sln;
		board = "RRWWRRBBRR", hand = "WB";
		auto res = sln.findMinStep(board, hand);
		Assert(2, res);
	}
	{
		Solution sln;
		board = "WWRRBBWW", hand = "WRBRW";
		auto res = sln.findMinStep(board, hand);
		Assert(2, res);
	}

	
	{
		Solution sln;
		board = "G", hand = "GGGGG";
		auto res = sln.findMinStep(board, hand);
		Assert(2, res);
	}
	{
		Solution sln;
		board = "WRRBBW", hand = "RB";
		auto res = sln.findMinStep(board, hand);
		Assert(-1, res);
	}
	{
		Solution sln;
		board = "WRRBBW", hand = "RB";
		auto res = sln.findMinStep(board, hand);
		Assert(-1, res);
	}

	
	{
		Solution sln;
		board = "RBYYBBRRB", hand = "YRBGB";
		auto res = sln.findMinStep(board, hand);
		Assert(3, res);
	}
	{
		Solution sln;
		board = "RRGGBBYYWWRRGGBB", hand = "RGBYW";
		auto res = sln.findMinStep(board, hand);
		Assert(-1, res);
	}

	
}

小的优化

class Solution {
public:
	int findMinStep(string board, string hand) {
		sort(hand.begin(), hand.end());
		queue<pair<string,string>> que;
		unordered_set<string> setHasDo;
		auto Add = [&](const string& s, const string& h)
		{
			const string cur = s + "-" + h;
			if (setHasDo.count(cur))
			{
				return;
			}
			setHasDo.emplace(cur);
			que.emplace(s,h);
		};
		Add(board, hand);
		while (que.size())
		{
			auto[s,h] = que.front();
			que.pop();	
			if (s.empty())
			{
				return hand.length() - h.length();
			}
			for (int i = 0 ; i < h.length();i++)
			{
				if (i && (h[i] == h[i - 1]))
				{//剪枝一
					continue;
				}
				string h2 = h.substr(0,i) + h.substr(i+1);
				for (int j = 0; j < s.length(); j++)
				{
					if (j&& (h[i] == s[j-1]))
					{
						continue;//剪枝二
					}
					if ((h[i] == s[j])||(j && (s[j - 1] == s[j])))
					{
						Add(Do(s, j, h[i]), h2);
					}
				}
			}
		}
		return -1;
	}
	string Do(const string& s, int l1,  const char& ch)
	{		
		stack<pair<char,int>> sta;
		auto Add = [&sta](const char& ch)
		{
			while (sta.size() && (sta.top().first != ch ) && (sta.top().second >= 3))
			{
				sta.pop();
			}
			if (sta.size()&& (sta.top().first == ch))
			{
				sta.top().second++;
			}
			else
			{
				sta.emplace(ch,1);
			}			
		};
		for (int i = 0; i < l1; i++)
		{
			Add( s[i]);
		}
		Add(ch);
		for (int i = l1; i < s.length() ; i++)
		{
			Add(s[i]);
		}
		string sRet;
		while (sta.size())
		{
			const auto [ch,iCnt] = sta.top();
			sta.pop();
			if (iCnt < 3)
			{//最后一个元素需要判断
				sRet += string(iCnt, ch);
			}
		}
		return sRet; //正序和反序是一样的
	}
};

实际上只需要考虑三种情况

  • 弹出一个球,三消。
  • 弹出两个同颜色的球三消。
  • 两个同颜色的球直接插入不同颜色的球。
class Solution {
public:
	int findMinStep(string board, string hand) {
		sort(hand.begin(), hand.end());
		queue<pair<string, string>> que;
		unordered_set<string> setHasDo;
		auto Add = [&](const string& s, const string& h)
		{
			bool bEmpty = s.empty();
			const string cur = s + "-" + h;
			if (setHasDo.count(cur))
			{
				return;
			}
			setHasDo.emplace(cur);
			que.emplace(s, h);
		};
		Add(board, hand);
		while (que.size())
		{
			auto [s, h] = que.front();
			que.pop();
			if (s.empty())
			{
				return hand.length() - h.length();
			}
			unordered_map<char, int> mCharCount;
			for (const auto& ch : h)
			{
				mCharCount[ch]++;
			}			
			for (int j = 0; j < s.length(); j++)
			{
				if ((j + 1 < s.length()) && (s[j] == s[j + 1]))
				{
					if (mCharCount.count(s[j]) && (mCharCount[s[j]] >= 1))
					{
						mCharCount[s[j]]--;
						Add(Do(s.substr(0,j+1)+s[j] + s.substr(j+1)),ToString(mCharCount));
						mCharCount[s[j]]++;
					}
					for ( auto& [ch, iCnt] : mCharCount)
					{
						if (ch != s[j])
						{
							iCnt--;
							Add(Do(s.substr(0, j+1) + ch + s.substr(j + 1)), ToString(mCharCount));
							iCnt++;
						}
					}
				}
				else
				{
					if (mCharCount.count(s[j]) && (mCharCount[s[j]] >= 2))
					{
						mCharCount[s[j]] -= 2;
						Add(Do(s.substr(0, j) + s[j] + s[j] + s.substr(j)), ToString(mCharCount));
						mCharCount[s[j]] += 2;
					}
				}				
			}
		}
		return -1;
	}
	string Do(const string& s)
	{
		stack<pair<char, int>> sta;
		for (const char& ch : s )
		{
			while (sta.size() && (sta.top().first != ch) && (sta.top().second >= 3))
			{
				sta.pop();
			}
			if (sta.size() && (sta.top().first == ch))
			{
				sta.top().second++;
			}
			else
			{
				sta.emplace(ch, 1);
			}
		}
		string sRet;
		while (sta.size())
		{
			const auto [ch, iCnt] = sta.top();
			sta.pop();
			if (iCnt < 3)
			{//最后一个元素需要判断
				sRet += string(iCnt, ch);
			}
		}
		return sRet; //正序和反序是一样的
	}
	string ToString(const unordered_map<char, int>& mCharCount)
	{
		string strRet;
		for (const auto& [ch, iCnt] : mCharCount)
		{
			strRet += string(iCnt, ch);
		}
		return strRet;
	}
};

进一步改进

hand的状态可以用位运算来表示,这可以提速,本题已经够复杂了。就不继续了。
可以用 深度优先,但要处理重复搜索。
已有状态: board用字符串,字典树提速。 hand用int 提速。

2023年1月版

class Solution {
public:
int findMinStep(string board, string hand) {
std::sort(hand.begin(), hand.end());
m_iMaxStep = hand.size();
std::unordered_set pre;
pre.emplace(hand + board);
for (int iStep = m_iMaxStep; iStep > 0; iStep–)
{
std::unordered_set dp;
for (const auto str : pre)
{
const string sHand = str.substr(0, iStep);
const string sBoard = str.substr(iStep);
if (“” == sBoard)
{
return m_iMaxStep - iStep;
}
Do(dp, sBoard, sHand);
}
pre.swap(dp);
}
if (pre.count(“”))
{
return m_iMaxStep;
}
return -1;
}
void Do(std::unordered_set& dp, const string& strBoard, const string& strHand)
{
for (int i = 0; i < strHand.size(); i++)
{
if ((i>0) && (strHand[i] == strHand[i - 1]))
{
continue;
}
string tmp = strHand;
tmp.erase(i, 1);
const char& ch = strHand[i];
for (int j = 0; j <= strBoard.size(); j++)
{
bool bNeedDo = false;
if (j < strBoard.length() && (strBoard[j] == ch))
{
bNeedDo = true;
}
if (j>0)
{
if ((j < strBoard.length()) && (strBoard[j-1] == strBoard[j])&&(ch != strBoard[j]))
{
bNeedDo = true;
}
}
if (!bNeedDo)
{
continue;
}
dp.emplace(tmp + Do(strBoard, j, ch));
}
}
}
string Do(string strBoard, int index, const char& ch)
{
strBoard.insert(index, std::string(“”) + ch);
Erase(strBoard, index);
return strBoard;
}
void Erase(string& strBoard, int index)
{
string res;
vector<pair<char, int>> st;
for (auto c : strBoard) {
while (!st.empty() && c != st.back().first && st.back().second >= 3) {
st.pop_back();
}
if (st.empty() || c != st.back().first) {
st.push_back({ c, 1 });
}
else {
st.back().second++;
}
}
if (!st.empty() && st.back().second >= 3) {
st.pop_back();
}
for (int i = 0; i < st.size(); ++i) {
for (int j = 0; j < st[i].second; ++j) {
res.push_back(st[i].first);
}
}
strBoard = res;
}
int m_iMaxStep;
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关

下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 **C+

+17**
如无特殊说明,本算法用**C++**实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上海AI实验室等开源,音频、音乐统一开发工具包Amphion

上海AI实验室、香港中文大学数据科学院、深圳大数据研究院联合开源了一个名为Amphion的音频、音乐和语音生成工具包。 Amphion可帮助开发人员研究文本生成音频、音乐等与音频相关的领域&#xff0c;可以在一个框架内完成&#xff0c;以解决生成模型黑箱、代码库分散、缺少评估…

C语言天花板——指针(进阶2)

好久不见了各位&#xff0c;甚是想念啊&#xff01;&#xff01;&#xff01;&#x1f3b6;&#x1f3b6;&#x1f3b6; 文章接上次的指针(进阶1)(http://t.csdnimg.cn/c39SJ)&#xff0c;我们继续发车咯&#x1f697;&#x1f697;&#x1f697; 五、函数指针 上次我们只是浅…

py的函数讲解

前言:本章节我们来讲函数&#xff0c;主播略微感觉到有点小难&#xff0c;友友们需要认真看 目录 一.初始函数 1.1关于函数 1.2举例 1.3小结 二.函数的基础语法 2.1关于函数的语法 2.2举例 2.3小结 三.函数的参数 3.1关于函数的参数 3.2举例 3.3小结 四.函数的返回…

【AI】 AIOTSummary

智能物联网(AIoT)是2018年兴起的概念,指系统通过各种信息传感器实时采集 各类信息(一般是在监控、互动、连接情境下的),在终端设备、边缘域或云中心 通过机器学习对数据进行智能化分析,包括定位、比对、预测、调度等。智能物联网(AIoT)是2018年兴起的概念,指系统通过…

UCB Data100:数据科学的原理和技巧:第十三章到第十五章

十三、梯度下降 原文&#xff1a;Gradient Descent 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 学习成果 优化复杂模型 识别直接微积分或几何论证无法帮助解决损失函数的情况 应用梯度下降进行数值优化 到目前为止&#xff0c;我们已经非常熟悉选择模型和相应损…

2023年全国职业院校技能大赛软件测试赛题—单元测试卷⑨

单元测试 一、任务要求 题目1&#xff1a;根据下列流程图编写程序实现相应分析处理并显示结果。返回文字“xa*a*b的值&#xff1a;”和x的值&#xff1b;返回文字“xa-b的值&#xff1a;”和x的值&#xff1b;返回文字“xab的值&#xff1a;”和x的值。其中变量a、b均须为整型…

VMware workstation安装MX-23.1虚拟机并配置网络

VMware workstation安装MX-23.1虚拟机并配置网络 MX Linux是基于Debian稳定分支的面向桌面的Linux发行&#xff0c;采用Xfce作为缺省桌面&#xff0c;是一份中量级操作系统。该文档适用于在VMware workstation平台安装MX-23.1虚拟机。 1.安装准备 1.1安装平台 Windows 11 …

Smallpdf扫描、转换、压缩、编辑、签名PDF

【应用名称】&#xff1a;Smallpdf: 扫描、转换、压缩、编辑、签名PDF 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#Smallpdf 【应用版本】&#xff1a;1.71.0 【应用大小】&#xff1a;150MB 【软件说明】&#xff1a;通过 Smallpdf&#xff0c;您可以&…

extern static 在linux 和 qt下差别

从五个点来说 1.p3.h 中 静态定义一个const的int 变量并且赋值 2.p5.h 声明函数test2的定义 3. 直接extern 引用声明 test1() 函数 而不是像p5.h一样 把函数声明写到头文件 在别的.c文件直接包含头文件 第二点和第三点 是引用声明函数的两种用法 4.main函数 中static静态定…

Vue3+Vite连接高德地图JS API——地图显示、输入搜索

1 开通高德地图Web端JS API服务 1、进入高德地图API官网&#xff08;https://lbs.amap.com/&#xff09;&#xff1a; 2、注册登录。 3、进入控制台。 4、点击“应用管理”&#xff0c;点击“我的应用”&#xff0c;创建新应用。 5、添加Key&#xff0c;服务平台选择“Web端&…

海外云手机助力企业拓展海外市场

在当前全球化的商业环境中&#xff0c;由于政策限制&#xff0c;许多企业面临着无法顺利将产品推广到国外的困境&#xff0c;使得海外市场的机遇白白流失。而随着科技的不断创新&#xff0c;一种解决企业海外拓展困境的工具应运而生&#xff0c;那就是海外云手机。本文将深入探…

使用Navicat导入csv数据至mysql

问题 使用Navicat导入csv数据至mysql 详细问题 笔者有已进行数据处理的csv&#xff0c;需要将数据信息导入mysql中 解决方案 步骤1、建立数据表&#xff0c;字段信息&#xff08;最好&#xff09;与csv字段信息保持一致&#xff0c;方便后续导入。 具体的&#xff0c;双击…

什么情况下考虑同时接入SD-WAN与MPLS

在企业网络架构中&#xff0c;SD-WAN和MPLS&#xff08;多协议标签交换&#xff09;都是常见的网络连接解决方案。而有时候&#xff0c;企业可能面临一种情况&#xff0c;即需要同时接入SD-WAN和MPLS。本文将探讨在什么情况下考虑同时使用这两种网络连接方式&#xff0c;并分析…

NVMe over TCP高性能文件存储,让未来照进现实,400us

你真的懂NVMe吗&#xff1f; 在说NVMe之前&#xff0c;我们觉得有必要先聊一聊NVM&#xff08;Non-Volatile Memory&#xff09;&#xff0c;即非易失性内存。从名字上看就知道&#xff0c;NVM是一种类内存式&#xff08;访问及寻址方式类似&#xff09;的设备&#xff0c;它必…

Postgresql常见(花式)操作完全示例

案例说明 将Excel数据导入Postgresql&#xff0c;并实现常见统计&#xff08;数据示例如下&#xff09; 导入Excel数据到数据库 使用Navicat工具连接数据库&#xff0c;使用导入功能可直接导入&#xff0c;此处不做过多介绍&#xff0c;详细操作请看下图&#xff1a; 点击“下…

vivado Revision Control

2020.2 只需要git 管理 prj.xpr 和 prj.srcs/ https://china.xilinx.com/video/hardware/ip-revision-control.html Using Vivado Design Suite with Revision Control https://www.xilinx.com/video/hardware/vivado-design-suite-revision-control.html http://www.xi…

UCB Data100:数据科学的原理和技巧:第十一章到第十二章

十一、恒定模型、损失和转换 原文&#xff1a;Constant Model, Loss, and Transformations 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 学习成果 推导出在 MSE 和 MAE 成本函数下恒定模型的最佳模型参数。 评估 MSE 和 MAE 风险之间的差异。 理解变量线性化的必要…

大创项目推荐 深度学习猫狗分类 - python opencv cnn

文章目录 0 前言1 课题背景2 使用CNN进行猫狗分类3 数据集处理4 神经网络的编写5 Tensorflow计算图的构建6 模型的训练和测试7 预测效果8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习猫狗分类 ** 该项目较为新颖&a…

如何配置Kafka账号密码

背景 我们需要与第三方系统进行数据同步&#xff0c;需要搭建公网Kafka&#xff0c;Kafka默认是没有用户密码校验的&#xff0c;所以我们需要配置用户名密码校验。 配置 新增JAAS配置文件 在conf目录下新增kafka_server_jaas.conf文件&#xff0c;文件内容如下&#xff1a;…

前端规范扩展

前端编程规范是基于原有vue2基础上那套《编码风格及标准》上&#xff0c;应用于vue3、typescript、vite2基础上延伸出来的扩展补充&#xff0c;持续完善 一、编码规范 ESLint 代码检测工具 Pretter 代码格式化工具配合双校验代码 Git 规范 - 编码工具 vscode 同步参考文档中…