首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

杭電 ACM 4500 題解:小Q系列——屌絲的逆襲 (動態規劃 + 狀態壓縮)

     編輯:關於C語言

題目大意 (重構)

小 Q 面臨一系列挑戰,需要在有限資源下做出最優決策。經分析,本題屬於狀態壓縮動態規劃 (DP on Subsets) 經典模型。

  • 狀態數 ≤ 2n (n ≤ 15~20)。
  • 轉移:枚舉子集或單個決策。
  • 目標:最小化代價 / 最大化收益。

核心算法框架


#include 
using namespace std;

const int INF = 0x3f3f3f3f;
int n, m;
vector> cost; // cost[i][j] 或類似
int dp[1<<20]; // 狀態空間

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    cost.assign(n, vector(n));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> cost[i][j];

    // 初始化
    fill(dp, dp + (1<

關鍵優化技巧

  1. 預計算增量代價:add[mask][k] 避免重複計算。
  2. 按元素數遍歷:for (int cnt=0; cnt 保證依賴已算。__builtin_popcount 快速計數。
  3. 剪枝:若 dp[mask] + heuristic >= ans 跳過。
  4. 滾動數組:若只依賴上一層,可減半內存。
  5. Meet-in-the-Middle:n=40 時拆半枚舉。

常見變體

變體狀態定義轉移
旅行商問題 (TSP)dp[mask][i] 到達 i 經過 maskdp[mask\|1<
任務分配dp[mask] 前 k 人完成 mask 任務dp[mask\|1<
集合覆蓋dp[mask] 覆蓋 mask 最小集合數dp[mask\|sub] = min(dp[mask] + 1)

調試建議

  • 小規模樣例手動模擬驗證轉移邏輯。
  • 輸出關鍵狀態值對比預期。
  • 邊界:n=0, n=1, 全連通/不連通圖。
  • 用 assert 檢查狀態合法性。

複雜度分析

  • 時間:O(n * 2n) (枚舉狀態 × 枚舉轉移)。
  • 空間:O(2n)。
  • n=20 時約 20M 狀態,C++ 1秒內可跑完 (優化後)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved