日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2025/3/19 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 连锁商店 状态压缩dp(女赛) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


題意 :

  • 每個(gè)點(diǎn)都屬于一家公司,每個(gè)點(diǎn)都對(duì)應(yīng)一個(gè)權(quán)值。對(duì)于一條路徑,屬于同一家公司的一些點(diǎn)的貢獻(xiàn)只能被算一次。給一張圖,路徑只能從小往大走,問從1走到每個(gè)點(diǎn)路徑上分別的最大權(quán)值和

思路 :

  • n最大為36,說明出現(xiàn)多個(gè)點(diǎn)的公司最大為n2\frac{n}{2}2n?,不難發(fā)現(xiàn),對(duì)于同一條路徑,如果這條路徑上有些點(diǎn)所屬公司只有這個(gè)點(diǎn),那么必然直接選上這個(gè)點(diǎn),對(duì)于只出現(xiàn)過一次的商店不需要存入狀態(tài)
  • 出現(xiàn)狀態(tài)分裂的狀況為出現(xiàn)多個(gè)點(diǎn)那些公司,這些才存入狀態(tài),那么時(shí)間復(fù)雜度是O(2n2?n2)O(2^{\frac{n}{2}}*n^{2})O(22n??n2),如果不優(yōu)化的話就是O(2n?n2)O(2^{n}*n^2)O(2n?n2)會(huì)T
  • 可以用二進(jìn)制壓縮出現(xiàn)多個(gè)點(diǎn)的公司的狀態(tài),dp[i][j]dp[i][j]dp[i][j]表示當(dāng)前在i點(diǎn),出現(xiàn)多個(gè)點(diǎn)的公司狀態(tà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到達(dá)}edge[1].pb(0);for (int i = 1; i <= n; i ++ ){int id = -1; // id為-1說明這個(gè)點(diǎn)所屬公司只有這家店,否則,id代表這個(gè)點(diǎn)所屬的公司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 // 需要判斷當(dāng)前取還是不取{for (int j = 0; j < (1 << (int)ve.size()); j ++ ) // 當(dāng)前,所有公司是否已經(jīng)被取過的狀態(tài){if (j & (1 << id)) // 當(dāng)前i這個(gè)點(diǎn)所在公司之前已經(jīng)取過,判斷當(dāng)前已經(jīng)取過的狀態(tài)和沒有取過然后加上當(dāng)前這個(gè){for (auto from : edge[i])dp[i][j] = max(dp[i][j], dp[from][j ^ (1 << id)] + w[c[i]]); // 后者是之前不取取當(dāng)前的}else // 計(jì)算不拿的狀態(tài){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; }

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。