f[i][j]表示从前i个物品中选且体积不超过j的所有选法
一定包含第i个物品有一个条件
即如果第i个物品加进来以后总体积仍<= j,那么第i个物品才能选
朴素版
#include<iostream>
using namespace std;
const int N = 35;
int w[N], v;
int f[N][20010];
int main(){
int n;
cin >> v >> n;
for(int i = 1;i <= n; i ++) cin >> w[i];
for(int i = 1;i <= n; i ++)
for(int j = 1; j <= v; j++){
f[i][j] = f[i - 1][j];//一定不包含第i个的情况
if(f[i - 1][j - w[i]] + w[i] <= j) //包含第i个的情况:如果前i-1种再加上第i种总体积<=j, 第i种才能选
f[i][j] = max(f[i][j], f[i - 1][j - w[i]] + w[i]);
}
cout << v - f[n][v] << endl;
return 0;
}
优化成一维算法
#include<iostream>
using namespace std;
const int N = 35;
int w[N], v;
int f[20010];
int main(){
int n;
cin >> v >> n;
for(int i = 1;i <= n; i ++) cin >> w[i];
for(int i = 1;i <= n; i ++)
for(int j = v; j >= f[j - w[i]] + w[i]; j--){
f[j] = max(f[j], f[j - w[i]] + w[i]);
}
cout << v - f[v] << endl;
return 0;
}