一、二维费用的背包问题
以二维费用的01背包问题为例。
8.二维费用的背包问题 题目链接
闫氏 DP 分析法:
- 状态表示: f [ i , j , k ] f[i,j,k] f[i,j,k]
(1) 集合:所有只从前 i i i 个物品选,且总体积不超过 j j j,总重量不超过 k k k 的选法
(2) 属性:Max - 状态计算:
(1) 所有选第 i i i 个物品的选法: f [ i − 1 , j − v 1 , k − v 2 ] f[i-1,j-v_1,k-v_2] f[i−1,j−v1,k−v2]
(2) 所有不选第 i i i 个物品的选法: f [ i − 1 , j , k ] f[i-1,j,k] f[i−1,j,k]
因此有 f [ i , j , k ] = m a x { f [ i − 1 , j − v 1 , k − v 2 ] , f [ i − 1 , j , k ] } f[i,j,k]=max\{f[i-1,j-v_1,k-v_2],f[i-1,j,k]\} f[i,j,k]=max{ f[i−1,j−v1,k−v2],f[i−1,j,k]}
当然,二维费用的背包问题也可结合完全背包、多重背包,或是求方案数、求具体方案等问题,而从一维费用到二维费用的转化并不难,这里不一一赘述。
代码实现:
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, V, M;
int f[N][N];
int main(){
scanf("%d %d %d", &n, &V, &M);
for (int i = 1; i <= n; i ++){
int v, m, w;
scanf("%d %d %d", &v, &m, &w);
for (int j = V; j >= v; j --)
for (int k = M; k >= m; k --)
f[j][k] = max(f[j][k], f[j - v][k - m] + w);
}
printf("%d", f[V][M]);
return 0;
}