藍橋杯算法之搜索章 - 4

目錄

文章目錄

前言

一、記憶化搜索

二、題目概略

三、斐波拉契數

四、Function

五、天下第一

六、滑雪

總結


親愛的讀者朋友們,大家好啊!不同的時間,相同的地點,今天又帶來了關于搜索部分的講解。接下來我將接著我前面文章的內容,開始講解以下記憶化搜索的部分了。

let's go!


前言

前面我們講解了剪枝的內容,我們接著它,繼續剪枝。

記憶化搜索就是我們剪枝的一大部分,我們接下來就學習我們的記憶化搜索吧!


一、記憶化搜索

記憶化搜索也是一種剪枝的策略

通過?個"備忘錄",記錄第?次搜索到的結果,當下?次搜索到這個狀態時,直接在"備忘錄"??找結果。

我們接下來就看看這部分的題目,在題目中來理解記憶化搜索吧

二、題目概略

509. 斐波那契數 - 力扣(LeetCode)

P1464 Function - 洛谷

P5635 【CSGRound1】天下第一 - 洛谷

P1434 [SHOI2002] 滑雪 - 洛谷

三、斐波拉契數

我們看完題目后,會發現很簡單,一個簡單的遞歸就可以解決了,所以我們很快就可以寫出這道題:

但是?我們執行時間怎么這么多?

如果卡時間我們不就過不了了嗎,所以該怎么辦?

我們畫一下對應的決策樹:

我們發現在遞歸的過程中,會出現很多重復的展開,我們就需要去將這些重復的內容全部去掉才對。這時候我們記憶化搜索就可以來幫助我們了

我們可以將對應的遞歸結果存下來,如果再次需要去遞歸這個數,那么我們判斷一下,直接拿對應的值即可

可以看一下它的數據范圍是小于等于30,所以我們創建一個35大小的數組即可:

int f[35];//備忘錄,存放對應下標i的斐波拉契值

這樣,我們就大幅度的降低了我們的時間消耗。記憶化搜索就幫我們剪掉對應的那些重復枝丫

四、Function

首先,先理解一下這個題目:

我們無非就是要設計一個遞歸函數,從之前的學習后,寫一個遞歸函數難度肯定不大。

但是題目后面又說,如果出現如w(15, 15, 15)的時候會出現很多的調用,這個時候我們就得需要記憶化搜索來記錄它的結果,剪掉多余的枝丫。

我們來實現一下最簡單的版本:

#include <iostream>
using namespace std;
typedef long long LL;
LL a, b, c;
LL dfs(LL a, LL b, LL c)
{if (a <= 0 || b <= 0 || c <= 0) return 1;if (a > 20 || b > 20 || c > 20) return dfs(20, 20, 20);if (a < b && b < c){return dfs(a, b, c - 1) + dfs(a, b - 1, c - 1) - dfs(a, b - 1, c);}else {return dfs(a - 1, b, c) + dfs(a - 1, b - 1, c) + dfs(a - 1, b, c - 1) - dfs(a - 1, b - 1, c - 1);}
}
int main()
{while(cin >> a >> b >> c){if (a == -1 && b == - 1 && c == -1) break;printf("w(%lld, %lld, %lld) = %lld\n", a, b, c, dfs(a, b, c));}return 0;
}

這是沒有記憶化搜索的版本,我們看看能不能通過呢?

會發現全部都超時了,所以我們的記憶化搜索是必須要增加上去的:

由于這里有三個數,我們要通過三個數來映射對應的值,所以我們要使用一個三維數組去映射:

#include <iostream>
using namespace std;
typedef long long LL;
const int N = 25;
LL f[N][N][N]; 
LL a, b, c;
LL dfs(LL a, LL b, LL c)
{if (a <= 0 || b <= 0 || c <= 0) return 1;if (a > 20 || b > 20 || c > 20) return dfs(20, 20, 20);if (f[a][b][c]) return f[a][b][c];//查找備忘錄 if (a < b && b < c){return f[a][b][c] = dfs(a, b, c - 1) + dfs(a, b - 1, c - 1) - dfs(a, b - 1, c);}else {return f[a][b][c] = dfs(a - 1, b, c) + dfs(a - 1, b - 1, c) + dfs(a - 1, b, c - 1) - dfs(a - 1, b - 1, c - 1);}
}
int main()
{while(cin >> a >> b >> c){if (a == -1 && b == - 1 && c == -1) break;printf("w(%lld, %lld, %lld) = %lld\n", a, b, c, dfs(a, b, c));}return 0;
}

我們這樣就通過了!

可能會有讀者問,為什么多組測試數據不清理數組呢?

那是因為我們后面也會用到這個備忘錄,并不需要清理

五、天下第一

講這道題的時候我需要先講一下取模運算的一些內容

對于取模的加法和乘法的性質:

(a + b + c) % p = (a % p + b % p + c % p) % p

(a * b * c) % p = (a % p * b % p * c % p) % p

在加法和乘法中,括號里面那一坨可以隨便加%p,并不會影響結果

那么現在再來理解一下這道題吧:

我們會有一個x和一個y進行不停的執行取模,誰先到0,誰就贏

都不能到0,就平局

題目很簡單,只需要通過遞歸去解決這個相同子問題即可:

還有就是每次x和y都會更新x = (x + y) % p, y = ((x + y) % p + y) % p = (x + y + y) % p

在不停的模中,就會出現重復的情況,我們就需要記錄下對應的結果

#include <iostream>
using namespace std;
const int N = 1e4 + 10;
char f[N][N];
int T, p;
char dfs(int x, int y)
{if (f[x][y]) return f[x][y];f[x][y] = '3';if (x == 0) return f[x][y] = '1';else if (y == 0) return f[x][y] = '2';return f[x][y] = dfs((x + y) % p, (x + y + y) % p);
}
int main()
{cin >> T >> p;while(T--){int x, y;cin >> x >> y;char ret = dfs(x, y);if (ret == '1') cout << 1 << endl;else if (ret == '2') cout << 2 << endl;else cout << "error" << endl;}return 0;
}

我們由于有x和y,就采用一個二維數組來映射即可

因為有三種結果,我們就不能直接使用bool數組來標記了,我們可以使用int或者char去記錄

但是int沒必要,有些浪費空間了,我們直接使用char數組去記錄即可。

我們一旦進入函數就要給它先打上平局的'3'才行,如果x或者y成了0,就修改為對應的1或者2

如果沒有最后返回的便是平局

六、滑雪

這道題跟前面幾道題的難度就不一樣了

我們最簡單的方法就是枚舉i,j

從(i, j)位置向四個方向去走,將最長的路徑找出來

dfs(i, j)返回這個點能滑的最遠距離

那么怎么讓這個往四個方向去走呢,看過前面章節內容的讀者就知道這時候我們就需要方向數組:dx[]和dy[]去更新我們的x和y了

我們先將最簡單代碼來寫一下:


#include <iostream>
using namespace std;
const int N = 110;
int a[N][N];
int r, c;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int dfs(int i, int j)
{int len = 1;for (int k = 0; k < 4; k++){int x = i + dx[k];int y = j + dy[k];if (x >= 1 && x <= r && y >= 1 && y <= c&& a[x][y] < a[i][j]){len = max(len, dfs(x, y) + 1);}}return len;
}int main()
{cin >> r >> c;for (int i = 1; i <= r; i++){for (int j = 1; j <= c; j++){cin >> a[i][j];}}int ret = 1;for (int i = 1; i <= r; i++){for (int j = 1; j <= c; j++){ret = max(ret, dfs(i, j));}}cout << ret << endl;return 0;
}

我們會發現還是有個例子超時了,我們不加記憶化搜索還是過不了。

由于每次去遍歷的時候都會遍歷到很多之前走過的節點,我們去遍歷的話就會浪費很多時間

我們就得想辦法將每個訪問過的點記憶下來,這樣再訪問這個點就可以直接拿到對應的值了。

#include <iostream>
using namespace std;
const int N = 110;
int a[N][N];
int r, c;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int f[N][N];
int dfs(int i, int j)
{if(f[i][j]) return f[i][j];int len = 1;for (int k = 0; k < 4; k++){int x = i + dx[k];int y = j + dy[k];if (x >= 1 && x <= r && y >= 1 && y <= c&& a[x][y] < a[i][j]){len = max(len, dfs(x, y) + 1);}}return f[i][j] = len;
}int main()
{cin >> r >> c;for (int i = 1; i <= r; i++){for (int j = 1; j <= c; j++){cin >> a[i][j];}}int ret = 1;for (int i = 1; i <= r; i++){for (int j = 1; j <= c; j++){ret = max(ret, dfs(i, j));}}cout << ret << endl;return 0;
}

我們發現這道題難度不大,只要通過深度搜索我們就可以很簡單的將對應的代碼寫出來。

通過添加映射的備忘錄將值記錄即可。

但是要注意的是,一定是要出現大量的相同的情況,我們才去使用備忘錄,記憶化搜索。

如上這樣會訪問到很多相同節點一般。

我們就要去使用記憶化搜索剪枝


總結

親愛的讀者朋友們,這篇文章希望大家能夠看完前面的文章再來讀,這樣的話會更加得心應手。

希望大家多多點贊 +?收藏 + 關注!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918620.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918620.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918620.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

抗量子加密技術前瞻:后量子時代的密碼學革命

目錄抗量子加密技術前瞻&#xff1a;后量子時代的密碼學革命1. 量子計算威脅現狀1.1 量子霸權里程碑1.2 受威脅算法1.3 時間緊迫性2. 抗量子密碼學體系2.1 技術路線對比2.2 數學基礎革新3. 標準化進程3.1 NIST PQC標準化時間線3.2 當前推薦算法4. 技術實現方案4.1 Kyber密鑰交換…

基于STM32設計的礦山環境監測系統(NBIOT)_262

文章目錄 一、前言 1.1 項目介紹 【1】開發背景 【2】研究的意義 【3】最終實現需求 【4】項目硬件模塊組成 1.2 設計思路 【1】整體設計思路 【2】上位機開發思路 1.3 項目開發背景 【1】選題的意義 【2】摘要 【3】國內外相關研究現狀 【5】參考文獻 1.4 開發工具的選擇 【1】…

電腦如何安裝win10專業版_電腦用u盤安裝win10專業版教程

電腦如何安裝win10專業版&#xff1f;電腦還是建議安裝win10專業版。Win分為多個版本&#xff0c;其中家庭版&#xff08;Home&#xff09;和專業版&#xff08;Pro&#xff09;是用戶選擇最多的兩個版本。win10專業版在功能以及安全性方面有著明顯的優勢&#xff0c;所以電腦還…

多語言文本 AI 情感分析 API 數據接口

多語言文本 AI 情感分析 API 數據接口 AI / 文本處理 AI 模型快速分析文本情感傾向 多語言文本 / 情感分析。 1. 產品功能 支持多語言文本情感分析&#xff1b;基于特定 AI 模型&#xff0c;快速識別文本情感傾向&#xff1b;適用于評論分析、輿情監控等場景&#xff1b;全接…

【R語言】R語言的工作空間映像(workspace image,通常是.RData)詳解

R語言的工作空間映像&#xff08;.RData&#xff09;詳解 在使用 R 語言時&#xff0c;你可能會注意到&#xff0c;每次退出 R 會彈出一個提示&#xff1a; Save workspace image? [y/n/c] 如果你使用的是 Rstudio 這個 IDE 來進行R語言的開發&#xff0c;那么可能彈出的提示…

在線 A2C實踐

在線 A2C&#xff08;Actor-Critic&#xff09;算法在推薦系統中的實踐&#xff0c;核心是將推薦過程建模為實時交互的強化學習問題&#xff0c;通過 Actor 生成推薦策略、Critic 評估策略價值&#xff0c;實現 “決策 - 反饋 - 更新” 的閉環。從樣本設計到最終上線&#xff0…

Eclipse RCP產品動態模塊設計

文章目錄 遇到問題具體實踐效果演示應用下載 遇到問題 如果你是一個To C產品的設計者&#xff0c;勢必會遇到用戶需求高度分化的場景&#xff0c;隨之而來的是繁雜的功能列表&#xff0c;如何讓用戶只接觸與其任務直接相關的功能&#xff0c;隱藏無關元素&#xff1f; 具體實…

NLP自然語言處理: FastText工具與遷移學習基礎詳解

FastText工具與遷移學習基礎詳解 一、知識框架總覽 FastText工具核心功能與應用場景FastText模型架構與工作原理層次Softmax加速機制哈夫曼樹概念與構建方法 二、FastText工具核心解析 2.1 功能定位 雙重核心功能 文本分類&#xff1a;可直接用于文本分類任務&#xff0c;快速生…

uni-app 生命周期詳解

概述 uni-app 基于 Vue.js 框架開發&#xff0c;其生命周期包含了三個層面&#xff1a; 應用生命周期&#xff1a;App.vue 的生命周期頁面生命周期&#xff1a;各個頁面的生命周期Vue 組件生命周期&#xff1a;Vue.js 原生的組件生命周期 這三種生命周期在不同場景下會按特定順…

MCU外設初始化:為什么參數配置必須優先于使能

在微控制器領域&#xff0c;初始化參數配置階段至關重要。此時&#xff0c;雖無電源驅動&#xff0c;但微控制器在使能信號到來前&#xff0c;借初始化參數配置這一精細步驟&#xff0c;開啟關鍵準備進程。初始化參數配置如同物理坐標錨定、邏輯指令部署、內在秩序預設&#xf…

AI一周事件(2025年8月6日-8月12日)

&#xff08;以下借助 DeepSeek-R1 & ChatGPT-5 輔助整理&#xff09; 一、AI 模型與算法進展 1. OpenAI 正式發布 GPT-5&#xff08;8月7日&#xff09; 事件&#xff1a;OpenAI 于 2025 年 8 月 7 日推出 GPT-5——其自稱擁有“PhD 級別”的智能&#xff0c;通過內置…

快速了解自然語言處理

在這個智能時代&#xff0c;我們每天都在和機器 “對話”—— 用語音助手查詢天氣、讓翻譯軟件跨越語言障礙、靠智能客服解決問題…… 這些便捷體驗的背后&#xff0c;都離不開自然語言處理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09; 技術。作為人工…

洛谷 P2607 [ZJOI2008] 騎士-提高+/省選-

題目描述 Z 國的騎士團是一個很有勢力的組織&#xff0c;幫會中匯聚了來自各地的精英。他們劫富濟貧&#xff0c;懲惡揚善&#xff0c;受到社會各界的贊揚。 最近發生了一件可怕的事情&#xff0c;邪惡的 Y 國發動了一場針對 Z 國的侵略戰爭。戰火綿延五百里&#xff0c;在和平…

不止于GET:掌握POST報錯注入的精髓

文章目錄引言POST請求簡述報錯注入核心思想關鍵前提實戰演練POST報錯注入與GET報錯注入的區別防御之道&#xff1a;如何避免POST報錯注入&#xff1f;引言 SQL注入是Web安全領域危害性最大、最常見、最持久的高危漏洞之一。它直接威脅到應用程序核心數據庫的安全&#xff0c;可…

01數據結構-Prim算法

01數據結構-Prim算法1.普利姆(Prim)算法1.1Prim算法定義1.2Prim算法邏輯1.3Prim代碼分析2.Prim算法代碼實現1.普利姆(Prim)算法 1.1Prim算法定義 Prim算法在找最小生成樹的時候&#xff0c;將頂點分為兩類&#xff0c;一類是在查找的過程中已經包含在生成樹中的頂點(假設為A類…

CacheBlend:結合緩存知識融合的快速RAG大語言模型推理服務

溫馨提示&#xff1a; 本篇文章已同步至"AI專題精講" CacheBlend&#xff1a;結合緩存知識融合的快速RAG大語言模型推理服務 摘要 大語言模型&#xff08;LLMs&#xff09;通常在輸入中包含多個文本片段&#xff0c;以提供必要的上下文。為了加速對較長LLM輸入的預…

Docker 在 Linux 中的額外資源占用分析

Docker 本身作為一個運行時環境&#xff0c;除了容器應用本身消耗的資源外&#xff0c;還會引入一些額外的開銷。主要體現在以下幾個方面&#xff1a; 1. 存儲空間占用 (Disk Space) 這是最顯著的額外開銷&#xff0c;主要來源于 Docker 的存儲驅動&#xff08;如 overlay2&…

[激光原理與應用-264]:理論 - 幾何光學 - 什么是焦距,長焦與短焦的比較

長焦與短焦透鏡是光學系統中兩類核心組件&#xff0c;其成像特性在焦距、視角、景深、像場特性及典型應用中存在顯著差異。以下從多個維度進行詳細對比&#xff1a;一、核心參數對比參數長焦透鏡短焦透鏡焦距范圍通常 >50mm&#xff08;全畫幅相機標準&#xff09;通常 <…

el-input 復制大量數據導致頁面卡頓問題解決

問題根源 復制粘貼操作會瞬間觸發大量 input 事件&#xff0c;導致 Vue 頻繁更新響應式數據&#xff0c;引發性能瓶頸。 解決方案&#xff1a;使用 .lazy 修飾符 <el-input v-model.lazy"inputValue" />

PCIe Electrical Idle Sequences ( EIOS and EIEOS )

前言 PCI Express (PCIe)協議中&#xff0c;EIOS (Electrical Idle Ordered Set) 和 EIEOS (Electrical Idle Exit Ordered Set) 是在高速鏈路管理和狀態切換過程中極為重要的特殊序列。下面做詳細解釋&#xff1a; 一、EIOS&#xff08;Electrical Idle Ordered Set&#xff0…