动态规划 递归关系
01 背包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <iostream> #include <algorithm> using namespace std ; const int N = 1010 ;int n, m;int v[N], w[N]; int f[N]; int main () { cin >> n >> m; for (int i = 1 ; i <= n; i ++ ) cin >> v[i] >> w[i]; for (int i = 1 ; i <= n; i ++) for (int j = m; j >= v[i]; j --) { f[j] = f[j]; f[j] = max(f[j], f[j - v[i]] + w[i]); } cout << f[m] << ' ' ; return 0 ; } 4 5 1 2 2 4 3 4 4 5 v[i] = 1 2 3 4 w[i] = 2 4 4 5 1 2 3 4 5 j 0 0 0 0 0 0 1 2 2 2 2 2 2 2 4 6 6 6 3 2 4 6 6 8 4 2 4 6 6 8 i
完全背包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <iostream> #include <algorithm> using namespace std ; const int N = 1010 ;int n, m;int v[N], w[N];int f[N];int main () { cin >> n >> m; for (int i = 1 ; i <= n; i ++ ) cin >> v[i] >> w[i]; for (int i = 1 ;i <= n; i ++) for (int j = v[i]; j <= m; j ++ ) f[j] = max(f[j], f[j - v[i]] + w[i]); cout << f[m] << endl ; return 0 ; }
//f[i,j] = Max(f[i][j],f[i-1,j-v]+w,f[i-1,j-2v]+2w,f[i-1,j-3v]+3w,…)
//f[i,j-v] = Max( f[i-1,j-v] ,f[i-1,j-2v]+w,f[i-1,j-3v]+2w,…)
完全背包与01背包的区别 多重背包
每个物品有限个
滑动窗口
通过二进制转化为01背包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <iostream> #include <algorithm> using namespace std ; const int N = 25000 ; int n, m;int v[N], w[N];int f[N];int main () { cin >> n >> m; int cnt = 0 ; for (int i = 1 ; i <= n; i ++ ) { int a, b, s; cin >> a >> b >> s; int k = 1 ; while (k <= s) { cnt ++; v[cnt] = a * k; w[cnt] = b * k; s -= k; k *= 2 ; } if (s > 0 ) { cnt ++; v[cnt] = a * s; w[cnt] = b * s; } } n = cnt; for (int i = 1 ; i <= n; i++) for (int j = m; j >= v[i]; j -- ) f[j] = max(f[j],f[j - v[i]] + w[i]); cout << f[m] << endl ; return 0 ; }
分组背包