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

HDU 5135:狀態壓縮 DP 組合三角形最大面積和

     編輯:關於C++

題目大意

給定 ≤12 條邊長,可組成若干不重疊的三角形(每條邊最多用一次),求最大總面積。三角形面積用海倫公式。

狀態壓縮 DP

  • 狀態 mask(2ⁿ)表示已使用邊的集合。
  • 預處理:枚舉所有三元組 (i,j,k),若能構成三角形,記錄 tri_mask = (1< 及面積 area。
  • DP 轉移:dp[mask | tri_mask] = max(dp[mask | tri_mask], dp[mask] + area),條件 (mask & tri_mask) == 0。
  • 答案為所有 dp[mask] 最大值。

代碼實現

#include <bits/stdc++.h>
using namespace std;

struct Tri { int mask; double area; };

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int n;
    while (cin >> n, n) {
        vector len(n);
        for (int &x : len) cin >> x;
        vector tris;
        for (int i = 0; i < n; ++i)
            for (int j = i+1; j < n; ++j)
                for (int k = j+1; k < n; ++k) {
                    int a=len[i], b=len[j], c=len[k];
                    if (a+b>c && a+c>b && b+c>a) {
                        double p = (a+b+c)/2.0;
                        double s = sqrt(p*(p-a)*(p-b)*(p-c));
                        tris.push_back({(1< dp(ALL, 0);
        double ans = 0;
        for (int mask = 0; mask < ALL; ++mask) {
            ans = max(ans, dp[mask]);
            for (auto &t : tris) {
                if ((mask & t.mask) == 0) {
                    int nmask = mask | t.mask;
                    dp[nmask] = max(dp[nmask], dp[mask] + t.area);
                }
            }
        }
        cout << fixed << setprecision(2) << ans << '\n';
    }
    return 0;
}

複雜度

  • 三元組枚舉:O(n³),n ≤ 12 → 220 次。
  • DP 狀態:2ⁿ ≤ 4096,每狀態遍歷所有三角形(≤220),總操作 < 10⁶。
  • 時間、空間均極小。

關鍵點

  • 海倫公式計算面積,double 精度足夠。
  • 輸出保留兩位小數 fixed << setprecision(2)。
  • 狀態壓縮 DP 是小規模組合優化問題的標準工具。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved