1. 程式人生 > 資訊 >Facebook 將關閉面部識別,官方談後續使用細節

Facebook 將關閉面部識別,官方談後續使用細節

揹包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為物品個數

混合三種揹包問題:

只需要在內層迴圈判斷是01揹包還是完全揹包、多重揹包即可

參考:dd大牛的《揹包九講》 - 賀佐安 - 部落格園 (cnblogs.com)