n 個石子(n ≤ 10),給定 n×n 矩陣 A[i][j] 表示合並石子 i 和 j 獲得的金幣(j 消失)。求合並所有石子(剩 1 個)的最大金幣數。
用二進制掩碼 mask 表示當前剩餘石子集合(1 為存在,0 為已合並消失)。初始狀態 (1<
dp[mask]:從狀態 mask 繼續合並到結束的最大金幣數。mask ^ (1<。dp[mask] = max_{i∈mask, j∈mask, j≠i} (dp[mask^(1<。dp[0] = 0(或單石子狀態 dp=0)。#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 15;
const int MAXS = 1<<10; // 1024
int n;
int A[MAXN][MAXN];
int dp[MAXS];
int solve(int mask) {
if (dp[mask] != -1) return dp[mask];
if (mask == 0) return 0;
int best = 0;
for (int i = 0; i < n; i++) if (mask & (1<
狀態壓縮 DP 經典應用:n ≤ 10 即可用 bitmask 表示集合。關鍵是明確「誰消失、誰獲得金幣」的轉移邏輯,並利用記憶化搜索自頂向下計算。代碼簡潔,是狀壓 DP 入門佳例。