Leetcode第451場周賽分析總結

在這里插入圖片描述

題目鏈接

競賽 - 力扣(LeetCode)全球極客摯愛的技術成長平臺

題目解析

A. 3560. 木材運輸的最小成本

AC代碼

class Solution {
public:long long minCuttingCost(int n, int m, int k) {if (n > m) swap(n, m);  // n <= m;using ll = long long;ll ans = 0;if (m > k) {ans = static_cast<ll>(k) * (m - k);}return ans;}
};

思路分析

看完題目后發現,只有三輛車,題目保證有解,意味著最多只有一根木棍的長度會大于k從而被切割。接下來問題轉換為,給定一根長度為n>k的木棍,將其切割為x+y=n兩部分,求z=x*y的最小值。我記得這是初中常見的一個約束,最大值出現在x=y=n/2的位置,最小值出現在兩端。實際上z是x的一個二次函數,在其作用域內先增加后減少。

x的最大值是k,那么z的最小值就是k*(n-k)。

可惜在實現的時候沒注意乘積會導致爆long long。其實返回值是long long就應該注意到的,不太應該。

靈神用Python代碼一行就搞定了。Python的int操作起來是更方便一些。在算法競賽有時會遇到一些大數運算(超過long long范圍的運算),如果用C++需要手動模擬實現,用Python就方便很多。

Python的int類型可以處理任意精度的整數,理論上沒有固定的大小限制,僅受限于計算機的可用內存(RAM)。

B. 3561.移除相鄰字符

AC代碼

class Solution {bool aux(char x, char y) {int diff = abs(x - y);return diff == 1 || diff == 25;}
public:string resultingString(string s) {string stk;for (auto c : s) {if (stk.empty()) {stk.push_back(c);} else {if (aux(stk.back(), c)) {stk.pop_back();} else {stk.push_back(c);}}}return stk;}
};

思路分析

注意到對于每次消除,至多影響前面的一個元素。每次都移除最左邊的字符對,模擬了一下發現類似棧的性質,用棧模擬。

靈神的代碼是先統一入棧,再考慮能否消除,在邏輯和實現上更簡潔一些。

C. 3562. 折扣價交易股票的最大利潤

AC代碼

class Solution {
public:int maxProfit(int n, vector<int>& present, vector<int>& future, vector<vector<int>>& hierarchy, int budget) {vector<vector<int>> graph(n);for (auto &edge : hierarchy) {int u = edge[0] - 1, v = edge[1] - 1;graph[u].push_back(v);}function<vector<vector<int>>(int)> dfs;dfs = [&](int u) -> vector<vector<int>> {vector f(budget + 1, vector<int>(2, 0));vector g = f;for (int v : graph[u]) {auto fv = dfs(v);for (int b = budget; b >= 0; b--) {for (int bv = 0; bv <= b; bv++) {for (int k = 0; k < 2; k++) {g[b][k] = max(g[b][k], g[b - bv][k] + fv[bv][k]);}}}}for (int b = 0; b <= budget; b++) {for (int k = 0; k < 2; k++) {int bu = present[u] / (k + 1);if (bu <= b) {f[b][k] = max(g[b][0], g[b - bu][1] + future[u] - bu);} else {f[b][k] = g[b][0];}}}return f;};return dfs(0)[budget][0];}
};

思路分析

比賽時想到如果員工的關系是一個鏈表,那我可以類似背包問題進行處理,對于每由于每個員工只影響自己的下屬(不會影響領導),所以有無后效性。需要最大化收益,所以有最優子結構。

每個員工有兩個狀態:

  • 可以使用的最大費用 b b b
  • 領導是否購買股票 k k k:0表示不買,1表示買

維護每個員工 u u u在給定狀態 ( b , k ) (b, k) (b,k)下他和下屬可以獲得的最大收益 f f f v v v表示他的下屬, c k c_k ck?表示在領導買股票狀態為 k k k的情況下購買股票的費用, p k p_k pk?表示購買股票的收益。

f u ( b , k ) = m a x { f v ( b , 0 ) , f v ( b ? c k , 1 ) + p k } f_u(b,k)= max\{f_v(b,0), f_v(b-c_k, 1)+p_k\} fu?(b,k)=max{fv?(b,0),fv?(b?ck?,1)+pk?}

然后就可以進行狀態轉移。可是面對一個樹結構,如果某員工決定給 t t t個下屬 b b b費用讓他們買股票,每個下屬應該用多少費用才能獲得最大收益呢?感覺得再需要一個回溯去搜索,簡單想了一下會超時。

在認真聽了靈神的講解后,發現自己對背包問題的理解還是太淺顯。

現在讓我們專心考慮這個子問題,我們可以先得到每個下屬在所有狀態下的收益 f v ( b , k ) f_{v}(b,k) fv?(b,k)(因為是在DP中),那對于某員工有 b b b費用的情況下,我們考慮前 i i i下屬消耗多少費用才能獲得最大收益 g i ( b , k ) g_i(b,k) gi?(b,k)

之所以考慮前 i i i個是因為員工之間的選擇除了消耗費用沒有額外的影響,因此無后效性,求最大收益所以有最優子結構。我們發現,員工對他們下屬的費用選擇形成了一個0-1背包問題,不過與普通背包問題不同的是,每個物品的價格和收益不是固定的,而是一組。

現在問題轉換為,對于某個員工,已經知道前 i ? 1 i-1 i?1個下屬可以獲得的最大收益 g i ? 1 ( b , k ) g_{i-1}(b,k) gi?1?(b,k),對第 i i i個員工,應該消耗多少費用才能使得 g i ( b , k ) g_i(b,k) gi?(b,k)最大,而這是一個貪心問題:

g i ( b , k ) = max ? 0 ≤ b v ≤ b g i ? 1 ( b ? b v , k ) + f v i ( b v , k ) g_i(b,k)=\operatorname* {max}_{0\le b_v\le b} g_{i-1}(b-b_v,k)+f_{v_i}(b_v,k) gi?(b,k)=0bv?bmax?gi?1?(b?bv?,k)+fvi??(bv?,k)

在算到所有的 g ( b , k ) g(b,k) g(b,k)后,我們就知道了給所有下屬b費用可以得到的最大收益,此時狀態轉移變成了:

f u ( b , k ) = m a x { g v ( b , 0 ) , g ( b ? c k , 1 ) + p k } f_u(b,k)= max\{g_v(b,0), g(b-c_k, 1)+p_k\} fu?(b,k)=max{gv?(b,0),g(b?ck?,1)+pk?}

最后的問題在大的框架上是一個樹型DP,每個節點上葉子到節點的狀態轉移是一個0-1背包問題,在這個0-1背包問題每個物體的選擇上又是一個貪心問題。

經過一段時間的理解我才梳理出整個思路,最后的代碼實現使用了0-1背包的滾動數組優化。自己的思維深度還是不夠,同時也應該梳理思考的順序,把已知、轉換過程都用紙筆記錄下來,可以幫助自己固定思維的結果,否則想著想著都糊涂了,人類的能力真是有局限的啊(迪奧笑)。

D. 3563. 移除相鄰字符后字典序最小的字符串

AC代碼

class Solution {static bool is_pair(char a, char b) {int diff = abs(a - b);return diff == 1 || diff == 25;}
public:string lexicographicallySmallestString(string s) {int n = s.size();vector dp2(n, vector<int>(n, 1));for (int i = 0; i < n; ++i) dp2[i][i] = 0;for (int l = 2; l <= n; ++l) {for (int i = 0; i + l - 1 < n; ++i) {int j = i + l - 1;dp2[i][j] = 0;if (is_pair(s[i], s[j])) {dp2[i][j] = dp2[i + 1][j - 1];if (dp2[i][j]) {continue;}}for (int k = i + 1; k < j; ++k) {dp2[i][j] = (dp2[i][k] && dp2[k + 1][j]);if (dp2[i][j]) {break;}}}}vector<string> dp(n + 1);for (int i = n - 1; i >= 0; --i) {auto &&ans = dp[i];ans.push_back(s[i]);ans.append(dp[i + 1]);for (int j = i + 1; j < n; ++j) {if (dp2[i][j]) {ans = min(ans, dp[j + 1]);}}}return dp[0];}
};

思路分析

比賽的時候沒有看清楚題目,想當然的以為和第二題一樣是從最左邊刪除,然后寫了一通模擬,結果理所當然地過不了。在任意位置刪除相鄰對的情況下,顯然已經不能模擬,只能考慮動態規劃或者貪心。

由于求的是最小的串,所以有最優子結構。可是前面的刪除似乎會影響后面的刪除,這樣看來是有后效性的,似乎看起來應該去思考貪心,但是貪心也沒有很好的想法,起決定作用的是前面的字符,但前面的字符有可能是通過后面的字符會刪除掉。

聽了靈神的講解后發現還是要沉下心去思考。我們上面覺得前面的字符可能和后面的字符配對刪除所以有后效性,但是如果確定刪除了就沒有后效性了。嘗試定義狀態dp[i]為i開始的字符串刪除配對后可以得到的最小字符串,考慮狀態轉移:

  • 如果s[i]不刪除,那顯然dp[i] = s[i] + dp[i + 1]

  • 關鍵在于s[i]如果可以刪除呢,問題變成了s[i]開始多少個字符可以刪掉。由于n很小,所以我們可以遍歷[i, j]字符串,如果s[i, j]可以刪除,dp[i]= min(dp[i], dp[j])。

    現在問題轉換為,如何快速判斷s[i, j]是否可以刪除。靈神說可以聯想到合法括號字符串(RBS),使用區間DP處理。難點在于,我聯想不到,注意力薄弱。

最終問題通過區間DP處理出哪些區間可以被消除,再用線性DP算出以某個字符開始可以得到的最小字符串。

總結

對這種需要多重轉換組合的問題,一旦卡住就沒法繼續下去。以后對于每個思考的方向,物理化自己的思維過程,把卡住的地方轉換成新的問題重新思考,不要卡住了就想來想去沒有進展。

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

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

相關文章

Linux中的shell腳本

什么是shell腳本 shell腳本是文本的一種shell腳本是可以運行的文本shell腳本的內容是由邏輯和數據組成shell腳本是解釋型語言 用file命令可以查看文件是否是一個腳本文件 file filename 腳本書寫規范 注釋 單行注釋 使用#號來進行單行注釋 多行注釋 使用 : " 注釋內容…

PHP與MYSQL結合中中的一些常用函數,HTTP協議定義,PHP進行文件編程,會話技術

MYSQL&#xff1a; 查詢函數: 執行查詢語句: 1.mysql_query("SQL語法"); 凡是執行操作希望拿到數據庫返回的數據進行展示的(結果返回: 數據結果); 2.執行結果的處理:成功為結果集&#xff0c;失敗為false; 成功返回結果:SQL指令沒有錯誤&#xff0c;但是查詢結果…

數學分析——一致性(均勻性)和收斂

目錄 1. 連續函數 1.1 連續函數的定義 1.2 連續函數的性質 1.2.1 性質一 1.2.2 性質二 1.2.3 性質三 1.2.4 性質四 2. 一致連續函數 2.1 一致連續函數的定義 2.2 一致連續性定理(小間距定理)(一致連續函數的另一種定義) 2.3 一致連續性判定法 2.4 連…

湖北理元理律師事務所:企業債務優化的科學路徑與人文關懷

湖北理元理律師事務所&#xff1a;企業債務優化的科學路徑與人文關懷 在中小企業經營壓力增大的背景下&#xff0c;如何平衡債務清償與員工生計成為關鍵課題。湖北理元理律師事務所聯合計劃集團公司&#xff0c;為服務企業設計了一套兼顧法律合規性與民生保障的債務解決方案&a…

樹莓派安裝openwrt搭建軟路由(ImmortalWrt固件方案)

&#x1f923;&#x1f449;我這里準備了兩個版本的openwrt安裝方案給大家參考使用&#xff0c;分別是原版的OpenWrt固件以及在原版基礎上進行改進的ImmortalWrt固件。推薦使用ImmortalWrt固件&#xff0c;當然如果想直接在原版上進行開發也可以&#xff0c;看個人選擇。 &…

一鍵凈化Excel數據:高性能Python腳本實現多核并行清理

摘要 本文分享兩個基于Python的Excel數據凈化腳本&#xff0c;通過多進程并行技術清除工作表內不可見字符、批注、單元格樣式等冗余內容&#xff0c;利用OpenPyXL實現底層操作&#xff0c;結合tqdm進度條和進程級任務分配&#xff0c;可快速處理百萬級單元格數據。適用于數據分…

【Netty】EventLoopGroup

在Netty的ServerBootstrap中設置兩個EventLoopGroup的作用是將網絡操作的兩個關鍵階段分離到不同的線程組中處理&#xff0c;從而優化性能并簡化并發控制。具體來說&#xff1a; 1. 兩個EventLoopGroup的角色 第一個EventLoopGroup&#xff08;通常稱為bossGroup&#xff09;&…

【前端】Vue中使用CKeditor作為富文本編輯器

官網https://ckeditor.com/ 此處記錄一下我在使用的時候具體初始化的代碼。 <template><div><textarea :id"id"></textarea></div> </template><script> export default {name: CkEditor,data: function () {return {id:…

前端面經 websocket

應用層協議&#xff0c;實現一個TCP連接上的全雙工通信&#xff0c;實時通訊 之前的實時WEB 實現輪詢 增加輪詢頻率 ws wss 明文版本 和 密文版本 特點 # 1 頭部小 2 更注重實時性

【筆記】suna部署之獲取 Supabase API key 和 project URL

#工作記錄 Supabase | The Open Source Firebase Alternative 一、注冊與登錄 方式一&#xff1a;GitHub 授權登錄 在登錄頁面選擇 “繼續使用 GitHub” &#xff0c;跳轉到 GitHub 授權頁面&#xff08;如圖 5 所示&#xff09;。確認 “Supabase 的想要訪問您的 [賬戶名] 帳…

爬蟲工具鏈的詳細分類解析

以下是針對爬蟲工具鏈的詳細分類解析&#xff0c;涵蓋靜態頁面、動態渲染和框架開發三大場景的技術選型與核心特性&#xff1a; &#x1f9e9; 一、靜態頁面抓取&#xff08;HTML結構固定&#xff09; 工具組合&#xff1a;Requests BeautifulSoup 適用場景&#xff1a;目標數…

STM32F407寄存器操作(ADC非連續掃描模式)

1.前言 書接上回&#xff0c;在看手冊的時候我突然發現手冊上還描述了另一種ADC掃描模式&#xff0c;即非連續掃描模式&#xff0c;想著連續掃描模式都已經探索過了&#xff0c;那就順手把非非連續模式研究一下吧。 2.理論 我們先看看手冊&#xff0c;這里我就以規則通道舉例…

spring切面

概念 兩個特點&#xff1a; IOC控制反轉AOP主要用來處理公共的代碼 例如一個案例就是添加用戶&#xff0c;重復的代碼包含了記錄日志、事務提交和事務回滾等&#xff0c;都是重復的&#xff0c;為了簡單&#xff0c;交給AOP來做。 即將復雜的需求分解出不同方面&#xff0c…

[Python] Python中的多重繼承

文章目錄 Lora中的例子 Lora中的例子 https://github.com/michaelnny/QLoRA-LLM/blob/main/qlora_llm/models/lora.py#L211C1-L243C10如果繼承兩個父類&#xff0c;并且父類的__init__參數不一樣&#xff0c;則可以顯式的調用父類init&#xff1b;如果用super().__init__()則需…

rsync服務的搭建

目錄 一、rsync介紹 rsync的安裝 二、rsync的語法 三、rsync命令使用 1. 本機同步 2. 遠程同步 四、rsync作為服務使用 1、嘗試啟動rsync程序 2、rsync的配置文件介紹 注意事項&#xff1a; 3. rsyncinotify實時同步 3.依賴服務托管xinetd&#xff08;CentOS 6中rs…

【C/C++】面試基礎題目收集

C 軟件開發面試中常見的刷題題目通常可分為以下幾大類&#xff1a;數據結構與算法、系統編程、面向對象設計、C 語言特性、并發編程等。 &#x1f9e0; 一、數據結構與算法&#xff08;力扣/牛客經典題&#xff09; 掌握 STL 和底層結構實現能力&#xff1a; &#x1f4cc; 數…

將手機網絡經USB數據線和本地局域網共享給華為AP6050DN無線接入點

引言 由于最近裝畢的新家所在的小區未能及時通寬帶,于是家中各類無線設備如何上網就成了首要要解決的問題。 鑒于家中要聯網的設備多、類型雜、支持頻段也不一,總是開手機熱點不是回事兒,于是就想著把手機網絡引至華為AP6050DN無線接入點中,讓家中所有的無線設備都能快速高…

【數據結構】圖論核心算法解析:深度優先搜索(DFS)的縱深遍歷與生成樹實戰指南?

深度優先搜索 導讀&#xff1a;從廣度到深度&#xff0c;探索圖的遍歷奧秘一、深度優先搜索二、算法思路三、算法邏輯四、算法評價五、深度優先生成樹六、有向圖與無向圖結語&#xff1a;深潛與回溯&#xff0c;揭開圖論世界的另一面 導讀&#xff1a;從廣度到深度&#xff0c;…

Flink CEP實踐總結:使用方法、常見報錯、優化與難點應對

Flink CEP實踐總結&#xff1a;使用方法、常見報錯、優化與難點應對 隨著實時數據分析需求的提升&#xff0c;Flink CEP&#xff08;Complex Event Processing&#xff0c;復雜事件處理&#xff09;成為事件流檢測中的利器。本文結合實際項目經驗&#xff0c;總結Flink CEP的基…

Python數據類型詳解:從字符串到布爾值,一網打盡

Python是現代編程語言中非常流行的一種&#xff0c;它的語法簡潔、易懂&#xff0c;非常適合初學者。而在Python編程中&#xff0c;“數據類型”是最基礎也是最重要的概念。理解這個概念&#xff0c;將為你之后的編程打下堅實的基礎。 1. 什么是數據類型&#xff1f; 在Pytho…