揹包記錄路徑
阿新 • • 發佈:2022-05-10
題意:
總公司擁有M臺 相同 的高效裝置,準備分給下屬的N個分公司。
各分公司若獲得這些裝置,可以為國家提供一定的盈利。盈利與分配的裝置數量有關。
問:如何分配這M臺裝置才能使國家得到的盈利最大?
求出最大盈利值。
分配原則:每個公司有權獲得任意數目的裝置,但總檯數不超過裝置數M。
- 我們把第\(i\)件物品分配到\(j\)件物品時花費定位\(j\),其價值就是\(a_{ij}\)
- 可以看作一個分組揹包的問題,每次從\(i\)組內選擇一個物品即可
- 記錄路徑時,僅需要記錄一下在第\(i\)個物品已裝容量為\(j\)時的轉移答案即可
- 輸出答案,遞迴輸出路徑即可
\(c11\) 書寫遞迴匿名函式function<返回型別(引數型別,...,引數型別)> 函式名 = [&](引數型別 引數名稱,...)
#include <bits/stdc++.h> using namespace std; int main() { int n,m; cin >> n >> m; vector<vector<int> >a(n + 1,vector<int>(m + 1)),pre(n + 1,vector<int>(m + 1)); vector<int>dp(m + 1); for(int i = 1;i <= n;i ++) { for(int j = 1;j <= m;j ++) { cin >> a[i][j]; } } for(int i = 1;i <= n;i ++) { for(int j = m;j >= 0;j --) { for(int k = 0;k <= m;k ++) { if(j < k) continue; if(dp[j] < dp[j - k] + a[i][k]) { dp[j] = dp[j - k] + a[i][k]; pre[i][j] = k; } } } } cout << dp[m] << '\n'; function<void(int,int)> output = [&](int x,int y) { if(x == 0) return ; int now = pre[x][y]; output(x - 1,y - now); cout << x << ' ' << now << '\n'; }; output(n,m); return 0; }