Facebook 將關閉面部識別,官方談後續使用細節
阿新 • • 發佈:2021-11-04
揹包DP(部分)
例:F - Piggy-Bank
完全揹包問題,區別是求的是最小值,所以只需要初始化為最大值,max改成min即可
程式碼示例:
//#pragma comment(linker, "/STACK:10240000000000,10240000000000") //#pragma GCC optimize(2) #include <bits/stdc++.h> #define For(i,a,b) for (int i=(a);i<=(b);++i) #define Fod(i,b,a) for (int i=(b);i>=(a);--i) #define mls multiset #define lb lower_bound #define ub upper_bound #define pb push_back #define pob pop_back #define itt iterator #define lowbit(x) x & (-x) #define clr(x) memset(x, 0, sizeof(x)); typedef long long ll; typedef unsigned long long ull; using namespace std; const int MAXN = 0x7fffffff; const int MOD = 1000000007; int f[10005]; int w[505]; int c[505]; int main () { ios::sync_with_stdio(false); cin.tie(0); int t; cin >> t; while(t--) { int e, ful; cin >> e >> ful; int n; int spa = ful - e; cin >> n; For(i, 1, n) cin >> w[i] >> c[i]; memset(f, 0x3f, sizeof f); f[0] = 0; For(i, 1, n) { For(v, c[i], spa) f[v] = min(f[v], f[v - c[i]] + w[i]); } if(f[spa] != 0x3f3f3f3f) printf("The minimum amount of money in the piggy-bank is %d.\n", f[spa]); else printf("This is impossible.\n"); } return 0; } /* f[i][v] 表示把前i種物品放進v容量的揹包裡能產生的最小价值 */
關於完全揹包 f只用了一維,並且第二層迴圈是c[i] - spa的解釋:
我們知道多重揹包問題可以由01揹包轉化而來,也就是每個物品多了個取k個的操作
第一種優化,我們可以把無限數量的單個物品,用\(2^k\)表示,也就是把\(2^k\)個第i個物品看成一個物品
最終優化,在01揹包中,我們內層迴圈的v是從spa開始然後到0的,如此是為了在進行狀態方程轉移時,我們保證對於考慮是否放第i個物品的狀態是從一個絕對沒有這件單品的子狀態轉移而來,因為每個物品只能放一個,但在多重揹包中則沒有這種顧慮,所以可以從0 - spa進行迴圈,如此一來可以節省一重的迴圈,是時間複雜度壓縮到O(VN),V為揹包最大容量,N為物品個數