CSP-J系列【2024】P11229 [CSP-J 2024] 小木棍題解

題目描述

小 S 喜歡收集小木棍。在收集了?n?根長度相等的小木棍之后,他閑來無事,便用它們拼起了數字。用小木棍拼每種數字的方法如下圖所示。

現在小 S 希望拼出一個整數,滿足如下條件:

  • 拼出這個數恰好使用?n?根小木棍;
  • 拼出的數沒有前導?0;
  • 在滿足以上兩個條件的前提下,這個數盡可能小。

小 S 想知道這個數是多少,可?n?很大,把木棍整理清楚就把小 S 折騰壞了,所以你需要幫他解決這個問題。如果不存在正整數滿足以上條件,你需要輸出??1?進行報告。

輸入格式

本題有多組測試數據。

輸入的第一行包含一個正整數?T,表示數據組數。

接下來包含?T?組數據,每組數據的格式如下:

一行包含一個整數?n,表示木棍數。

輸出格式

對于每組數據:輸出一行,如果存在滿足題意的正整數,輸出這個數;否則輸出??1。

輸入輸出樣例

輸入 #1復制

5
1
2
3
6
18

輸出 #1復制

-1
1
7
6
208

說明/提示

【樣例 1 解釋】

  • 對于第一組測試數據,不存在任何一個正整數可以使用恰好一根小木棍擺出,故輸出??1。
  • 對于第四組測試數據,注意?0?并不是一個滿足要求的方案。擺出?9、41?以及?111?都恰好需要?6?根小木棍,但它們不是擺出的數最小的方案。
  • 對于第五組測試數據,擺出?208?需要?5+6+7=18?根小木棍。可以證明擺出任何一個小于?208?的正整數需要的小木棍數都不是?18。注意盡管拼出?006?也需要?18?根小木棍,但因為這個數有前導零,因此并不是一個滿足要求的方案。

【數據范圍】

對于所有測試數據,保證:1≤T≤50,1≤n≤105。

測試點編號n≤特殊性質
120
250
3103A
4,5105A
6103B
7,8105B
9103
10105

特殊性質 A:保證?n?是?7?的倍數且?n≥100。

特殊性質 B:保證存在整數?k?使得?n=7k+1,且?n≥100。

題目概述與分析

小木棍問題是2024年CSP-J競賽中的一道經典題目,考察選手對搜索算法和剪枝優化的掌握。題目描述有n根長度不同的小木棍,需要將它們拼接成若干根長度相同的長木棍,求可能的最小原始長木棍長度。

這個問題可以建模為組合優化問題,需要綜合考慮所有可能的組合方式。我們將介紹兩種不同的解法:深度優先搜索(DFS)剪枝法和動態規劃法。

解法一:DFS剪枝法

算法思路

  1. 使用深度優先搜索嘗試所有可能的組合
  2. 通過多種剪枝策略優化搜索效率
  3. 從最大可能長度開始向下搜索
  4. 時間復雜度取決于剪枝效果,最壞情況下O(n!)
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;vector<int> sticks;
vector<bool> used;
int n, total_len, max_len;bool dfs(int cnt, int cur_len, int start, int target) {if (cnt == total_len / target) return true;if (cur_len == target) return dfs(cnt + 1, 0, 0, target);for (int i = start; i < n; ++i) {if (!used[i] && cur_len + sticks[i] <= target) {if (i > 0 && sticks[i] == sticks[i-1] && !used[i-1]) continue;used[i] = true;if (dfs(cnt, cur_len + sticks[i], i + 1, target)) return true;used[i] = false;if (cur_len == 0) break;}}return false;
}int main() {cin >> n;sticks.resize(n);used.resize(n, false);total_len = 0;max_len = 0;for (int i = 0; i < n; ++i) {cin >> sticks[i];total_len += sticks[i];max_len = max(max_len, sticks[i]);}sort(sticks.begin(), sticks.end(), greater<int>());for (int len = max_len; len <= total_len; ++len) {if (total_len % len != 0) continue;fill(used.begin(), used.end(), false);if (dfs(0, 0, 0, len)) {cout << len << endl;return 0;}}cout << total_len << endl;return 0;
}

該實現使用DFS加多種剪枝策略,包括排序優化、跳過重復值和提前終止等,能有效提高搜索效率。

解法二:動態規劃法

算法思路

  1. 將問題轉化為背包問題的變種
  2. 使用位運算狀態壓縮
  3. 記錄可達的長度組合
  4. 時間復雜度O(n*sum),適合sum較小的情況
#include <iostream>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;int main() {int n;cin >> n;vector<int> sticks(n);int sum = 0;for (int i = 0; i < n; ++i) {cin >> sticks[i];sum += sticks[i];}sort(sticks.begin(), sticks.end());for (int len = sticks.back(); len <= sum; ++len) {if (sum % len != 0) continue;int k = sum / len;vector<bitset<100>> dp(k + 1);dp[0][0] = 1;for (int stick : sticks) {for (int i = k; i >= 0; --i) {for (int j = len; j >= 0; --j) {if (dp[i][j]) {if (j + stick <= len) {dp[i][j + stick] = 1;}if (i + 1 <= k && stick <= len) {dp[i + 1][stick] = 1;}}}}}if (dp[k][0]) {cout << len << endl;return 0;}}cout << sum << endl;return 0;
}

動態規劃解法通過狀態壓縮記錄可達的長度組合,適合小規模數據,但空間復雜度較高。

算法對比分析

方法時間復雜度空間復雜度適用場景
DFS剪枝法取決于剪枝效果O(n)數據規模中等,剪枝有效
動態規劃法O(n*sum)O(k*len)sum值較小的情況

關鍵問題詳解

剪枝策略優化

  1. 從大到小排序木棍,優先嘗試長木棍
  2. 跳過相同長度的重復嘗試
  3. 當前組合失敗時及時回溯
  4. 限制搜索的起始位置避免重復

邊界情況處理

  1. 所有木棍長度相同的情況
  2. 無法分割的情況
  3. 極端大規模數據測試
  4. 包含長度為1的木棍的情況

性能優化建議

  1. 預處理時計算所有可能的候選長度
  2. 使用更高效的數據結構存儲狀態
  3. 并行化處理可能的候選長度
  4. 提前終止不可能的組合

數學原理分析

  1. 組合數學中的分割問題
  2. 數論中的因數分解應用
  3. 搜索算法的剪枝理論
  4. 動態規劃的最優子結構性質

實際應用價值

這類算法在以下領域有重要應用:

  1. 資源分配與調度
  2. 貨物裝載優化
  3. 時間表安排
  4. 工業生產中的材料切割

擴展思考

  1. 如果木棍有不同顏色限制如何處理?
  2. 如果允許部分不匹配的情況怎么解決?
  3. 如何擴展到三維空間的材料分割?
  4. 多目標優化情況下如何調整算法?

掌握這類組合優化問題的解法,不僅能提升競賽能力,也對解決實際工程問題有很大幫助。建議先理解基礎算法原理,再針對具體問題特點進行優化。

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

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

相關文章

C# 繼承 虛方法

繼承 虛方法 &#xff08;重寫&#xff09; virtual 虛方法的關鍵字 override 重寫的關鍵字 練習&#xff1a; 繼承 繼承&#xff1a;很多類有相似的數據 相同的屬性 相同的方法 也有不同的 這個時候就可以使用繼承 讓多個類去繼承自某個具有相同數據的基類(父類) 這…

Java 堆(優先級隊列)

文章目錄優先級隊列模擬實現優先級隊列向下調整建堆向上調整建堆堆的刪除priorityQueue構造方法大根堆和小根堆的向上調整比較方法擴容面試題堆排序優先級隊列 priorityqueue&#xff1a;底層是一顆完全二叉樹 小根堆&#xff1a;根比左右孩子都小大根堆&#xff1a;根比左右…

在.NET Core API 微服務中使用 gRPC:從通信模式到場景選型

目錄 一、gRPC 基礎&#xff1a;為什么它適合微服務&#xff1f; 二、gRPC 的四種通信模式及.NET Core 實現 1. 一元 RPC&#xff08;Unary RPC&#xff09;&#xff1a;最基礎的請求 - 響應模式 2. 服務器流式 RPC&#xff08;Server Streaming RPC&#xff09;&#xff1…

HTML零基礎快速入門教程(詳細篇)

本文詳細介紹HTML零基礎快速入門的基礎知識&#xff0c;包括HTML的介紹、語言的一些實際作用、語法規范注意&#xff0c;如標簽結構、標簽屬性、大小寫不敏感等&#xff0c;還介紹了HTML文件的具體書寫規則&#xff0c;如文件擴展名、文檔類型聲明和HTML結構以及具體的一些HTML…

LLM評測框架Ragas:SQL指標(解決了Ollama推理框架不支持的問題)

SQL類的度量指標是指運行SQL后的結果和預期之間的一個度量值。 datacompy score datacompy score 使用DataCompy(一個比較pandas的數據格式的python類,所以需要按照datacompy:pip install datacompy),默認是按照rows比較,也可以設置按照columns比較,這個事通過mode參數…

ubuntu24 ros2 jazzy

安裝2 software & update 選擇其它 安裝 一、前提準備 檢查操作系統版本&#xff1a; 確保你的系統版本是Ubuntu 24.04。你可以通過運行lsb_release -a命令來檢查當前的系統版本。 設置UTF-8支持&#xff1a; ROS 2需要UTF-8編碼支持。你可以通過以下命令來檢查和設置UTF…

設備虛擬化技術

設備虛擬化技術概述設備虛擬化技術通過軟件模擬物理硬件設備&#xff0c;使多個操作系統或應用程序能夠共享同一臺物理設備。它廣泛應用于云計算、服務器整合和測試環境等領域。核心目標是提高資源利用率、隔離性和靈活性。?當接入的用戶數增加到原交換機端口密度不能滿足接入…

開發避坑短篇(3):解決@vitejs plugin-vue@5.0.5對Vite^5.0.0的依賴沖突

異常信息 # npm resolution error reportWhile resolving:system3.8.8 Found: vite6.2.3 node_modules/vitedev vite"6.2.3" from the root projectCould not resolve dependency: peer vite"^5.0.0" from vitejs/plugin-vue5.0.5 node_modules/vitejs/plu…

k8s快速部署(親測無坑)

文章目錄k8s快速部署&#xff08;親測無坑&#xff09;一、網絡劃分二、CentOS7設置 標題固定IP和阿里云YUM源三、主機環境配置四、虛擬機的拷貝五、安裝docker(每臺主機都需要安裝)六、安裝kubelet,kubeadm,kubectl(每臺機器都需要執行)遇到的問題參考文檔k8s快速部署&#xf…

簡易RAG問答引擎的構建與體驗

RAG&#xff08;檢索增強生成&#xff09;是結合檢索與生成式 AI 的技術框架。核心邏輯是先從外部知識庫精準檢索相關信息&#xff0c;再將其作為上下文輸入大模型生成回答。技術上依賴檢索引擎&#xff08;如向量數據庫、BM25&#xff09;、大語言模型&#xff08;如 GPT、LLa…

C++11特性學習 Day1

nullptr對于c中null (void*)0&#xff0c;所以在為函數傳參傳入0時&#xff0c;無法清楚地分辨是int類型的0還是指的是空指針null在C11中清晰的將空指針變為了nullptr&#xff0c;0專指int型的數字0override關鍵字在子類中對父類的函數的覆寫之后加上override關鍵字&#xff0…

微算法科技(NASDAQ: MLGO)探索優化量子糾錯算法,提升量子算法準確性

隨著量子計算技術的飛速發展&#xff0c;量子計算機在解決復雜計算問題上的潛力日益顯現。然而&#xff0c;量子計算面臨的一個重大挑戰是量子比特的脆弱性&#xff0c;即量子比特容易受到環境噪聲和干擾的影響&#xff0c;導致量子態的塌縮和計算結果的錯誤。微算法科技&#…

MongoDB數據庫詳解-針對大型分布式項目采用的原因以及基礎原理和發展-卓伊凡|貝貝|莉莉

MongoDB數據庫詳解-針對大型分布式項目采用的原因以及基礎原理和發展-卓伊凡|貝貝|莉莉由于老產品即時通訊私有化軟件就是采用MongoDB &#xff0c;但是版本實在太低&#xff0c;要做大更新&#xff0c;其次針對10年前完美運營的項目來到10年后的現在就不一定行&#xff0c;優雅…

Kotlin 中的單例模式(Singleton)與對象聲明

在 Kotlin 中&#xff0c;類描述的是一種通用結構&#xff0c;可以多次實例化&#xff0c;也可以用多種方式實例化。但有時我們只需要單個實例&#xff0c;不多不少。單例模式能幫你更好地組織代碼&#xff0c;把相關的方法聚合在一起。 單例模式是什么&#xff1f; 單例模式是…

Shell 編程基礎入門從認識到實戰

對于剛接觸 Linux 或 Unix 系統的開發者來說&#xff0c;Shell 腳本往往是自動化操作的第一道門檻。它不像 Python 那樣語法簡潔&#xff0c;也不像 Java 那樣有完善的面向對象體系&#xff0c;但卻能以極少的代碼實現強大的系統管理功能。本文將從 Shell 的基本概念講起&#…

混合遺傳粒子群算法在光伏系統MPPT中的應用研究

混合遺傳粒子群算法在光伏系統MPPT中的應用研究 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家&#xff0c;覺得好請收藏。點擊跳轉到網站。 摘要 本文針對光伏系統最大功率點跟蹤(MPPT)問題&#xff0…

機器視覺的布料絲印應用

在紡織印染行業&#xff0c;布料絲印工藝的精度直接決定產品外觀質量與市場競爭力。傳統絲印設備依賴機械定位與人工校準&#xff0c;面對高密度圖案、柔性面料或復雜紋理時&#xff0c;易出現套色偏移、油墨滲透不均等問題&#xff0c;導致良品率波動與生產成本攀升。 隨著機…

前端常用類庫

常用類庫 類庫作用 類庫可以幫助我們快速實現項目業務的開發與功能的實現, 幫助我們解放勞動力提高生產效率, 前端中的類庫與框架都是由原生javascript編寫, 提供給其他開發者應用于某一業務環境或者需求。一般有開發者/團隊開源維護. 優秀的類庫需要具備高度封裝可用, 穩定, …

通俗易懂循環神經網絡(RNN)指南

本文用直觀類比、圖表和代碼&#xff0c;帶你輕松理解RNN及其變體&#xff08;LSTM、GRU、雙向RNN&#xff09;的原理和應用。什么是循環神經網絡 循環神經網絡&#xff08;Recurrent Neural Network, RNN&#xff09;是一類專門用于處理序列數據的神經網絡。與前饋神經網絡不同…

【SVM】支持向量機實例合集

基于Java的SVM(支持向量機)實例合集 以下是一個基于Java的SVM(支持向量機)實例合集,包含核心代碼示例和應用場景說明。這些例子基于流行的機器學習庫(如LIBSVM、Weka、JSAT)實現。 數據準備與加載 使用LIBSVM格式加載數據集: // 加載LIBSVM格式數據 svm_problem pr…