实质上就是对于01背包的问题再加上了一个条件而已。
给出两种做法:
第一、DFS,超时。
在dfs中,我们在判断条件的时候千万不要分开判断条件,这样会造成误判,因为这里有两个限制条件,我们如果考虑了两种或者三种,也不一定对,会出现不必要的bug,我们直接写满足容量足够并且重量足够的条件就行了,就省了判断比较坏的情况了。其他的思路也就是和01背包是一样的。
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 1005
#define int long long
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
int n, M, res, V;
int v[MAX];
int m[MAX];
int w[MAX];
int f[MAX];//前i个菜之后剩余j元
int g[MAX];
int dfs(int u, int sumV, int sumM) {
if (u > n)
return 0;
else {
if (sumM >= m[u] && sumV >= v[u])
return max(dfs(u + 1, sumV, sumM), dfs(u + 1, sumV - v[u], sumM - m[u]) + w[u]);
else
return dfs(u + 1, sumV, sumM);
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n >> V >> M;
_for(i, 1, n + 1) {
cin >> v[i] >> m[i] >> w[i];
}
res = dfs(1, V, M);
cout << res;
return 0;
}
第二种、记忆化搜索
如果你开一个三维的空间的话,按照题目的数据范围,这个数组绝对会暴空间。
第三种、DP
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 1005
#define int long long
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
int n, M, res, V;
int v[MAX];
int m[MAX];
int w[MAX];
int g[MAX];
int f[MAX][MAX];
int dfs(int u, int sumV, int sumM) {
if (u > n)
return 0;
else {
if (sumM >= m[u] && sumV >= v[u])
return max(dfs(u + 1, sumV, sumM), dfs(u + 1, sumV - v[u], sumM - m[u]) + w[u]);
else
return dfs(u + 1, sumV, sumM);
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n >> V >> M;
for (int i = 1; i <= n;i++) {
cin >> v[i] >> m[i] >> w[i];
}
for (int i = 1; i <= n; i++) {
for (int j = V; j >= v[i]; j--) {
for (int k = M; k >= m[i]; k--) {
f[j][k] = max(f[j - v[i]][k - m[i]] + w[i], f[j][k]);
}
}
}
cout << f[V][M];
return 0;
}
这里就不细讲了,也就是01背包的模板思路。
有人会问,在循环那里的判断条件为什么没有了呢?注意看循环里面的判断条件,这里我已经改成了v[i]和m[i],也就是说,我们在循环里面就已经判断了这个条件了,也就不需要再分支了。