日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

连锁商店 状态压缩dp(女赛)

發布時間:2025/3/19 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 连锁商店 状态压缩dp(女赛) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


題意 :

  • 每個點都屬于一家公司,每個點都對應一個權值。對于一條路徑,屬于同一家公司的一些點的貢獻只能被算一次。給一張圖,路徑只能從小往大走,問從1走到每個點路徑上分別的最大權值和

思路 :

  • n最大為36,說明出現多個點的公司最大為n2\frac{n}{2}2n?,不難發現,對于同一條路徑,如果這條路徑上有些點所屬公司只有這個點,那么必然直接選上這個點,對于只出現過一次的商店不需要存入狀態
  • 出現狀態分裂的狀況為出現多個點那些公司,這些才存入狀態,那么時間復雜度是O(2n2?n2)O(2^{\frac{n}{2}}*n^{2})O(22n??n2),如果不優化的話就是O(2n?n2)O(2^{n}*n^2)O(2n?n2)會T
  • 可以用二進制壓縮出現多個點的公司的狀態,dp[i][j]dp[i][j]dp[i][j]表示當前在i點,出現多個點的公司狀態為j
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <vector> #include <unordered_map> #define fi first #define se second #define pb push_backusing namespace std;typedef long long ll;const int N = 40, M = 1 << 20;int n, m; int c[N], w[N]; int dp[40][M]; vector<int> edge[N]; unordered_map<int, int> mp; vector<int> ve;void solve() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; i ++ ){scanf("%d", &c[i]);mp[c[i]] ++ ;}for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]);for (auto w : mp)if (w.se > 1)ve.pb(w.fi);for (int i = 1, u, v; i <= m; i ++ ){scanf("%d%d", &u, &v);edge[v].pb(u); // v能由u到達}edge[1].pb(0);for (int i = 1; i <= n; i ++ ){int id = -1; // id為-1說明這個點所屬公司只有這家店,否則,id代表這個點所屬的公司for (int j = 0; j < (int)ve.size(); j ++ )if (c[i] == ve[j]){id = j;break;}if (id == -1) // 直接加上{for (int j = 0; j < (1 << (int)ve.size()); j ++ )for (auto from : edge[i])dp[i][j] = max(dp[i][j], dp[from][j] + w[c[i]]);}else // 需要判斷當前取還是不取{for (int j = 0; j < (1 << (int)ve.size()); j ++ ) // 當前,所有公司是否已經被取過的狀態{if (j & (1 << id)) // 當前i這個點所在公司之前已經取過,判斷當前已經取過的狀態和沒有取過然后加上當前這個{for (auto from : edge[i])dp[i][j] = max(dp[i][j], dp[from][j ^ (1 << id)] + w[c[i]]); // 后者是之前不取取當前的}else // 計算不拿的狀態{for (auto from : edge[i])dp[i][j] = max(dp[i][j], dp[from][j]);}}}int ans = 0;for (int j = 0; j < (1 << (int)ve.size()); j ++ ) ans = max(ans, dp[i][j]);cout << ans << endl;} }int main() { // ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);int _ = 1; // cin >> _;while (_ -- ){solve();}return 0; }

總結

以上是生活随笔為你收集整理的连锁商店 状态压缩dp(女赛)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。