首先作者DFS暴力了一下,发现这里面会有数据TLE,也就能拿80%的数据分。
DFS就不用多说了,作者用的都是自己的模板,可以去前面的博客看看,这里用的递归是指数型递归,也就是选与不选的问题。
#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 100
#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;
using PII=pair<int, int>;
int n,V,m,res=INT_MAX;
int w[MAX];
int st[MAX];
void dfs(int u, int sumV) {
if (sumV < 0)
return;
if (u > n)
{
res = min(res, sumV);
return;
}
if (!st[u]&&w[u] > sumV)
dfs(u + 1, sumV);
st[u] = 1;
dfs(u + 1, sumV - w[u]);
st[u] = 0;
st[u] = 2;
dfs(u + 1,sumV);
st[u] = 0;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> V;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i];
}
dfs(1,V);
cout << res;
return 0;
}
接下来就是DP的优化了:
我们从刚刚的DFS中知道了,如果说我们按照逆向思维进行思考的话,也就是从可以用的体积里面去减,最后得到的就是剩下的体积,那么我们就可以用这样的思维去做。
其实就是01背包问题的一种变形,这里的w[i]其实也就是体积,也就是说,我们在考虑数组里面减去体积的同时还需要把每个物品的体积看作是价值,然后求出来的最大价值其实就是我们最多能装的最大体积,这个时候我们只需要将给我们的容量减去它就是结果了。
注意:这里开数组不能开小,需要开到20000,因为体积的范围很大,我们也不能用二维数组,所以需要用滚动数组进行节省空间。
上代码:
#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 20005
#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;
using PII=pair<int, int>;
int n,V,m,res=INT_MAX;
int w[MAX];
int f[MAX];
int st[MAX];
void dfs(int u, int sumV) {
if (sumV < 0)
return;
if (u > n)
{
res = min(res, sumV);
return;
}
if (!st[u]&&w[u] > sumV)
dfs(u + 1, sumV);
st[u] = 1;
dfs(u + 1, sumV - w[u]);
st[u] = 0;
st[u] = 2;
dfs(u + 1,sumV);
st[u] = 0;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> V;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i];
}
for (int i = 1; i <= n; i++) {
for (int j = V; j >= 0; j--) {
if (j < w[i])
f[j] = f[j];
else
f[j] = max(f[j], f[j - w[i]] + w[i]);
}
}
cout << f[V];
return 0;
}