//优化空间前
//TLE! 时间复杂度为 O(N*V^2) 1e9次运算量
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m;
int v[N], w[N];
int f[N][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 = 0; j <= m; j ++)
for (int k = 0; k * v[i] <= j; k ++) { //这里是因为有k,所以可以不用写f[i][j] = f[i-1][j]; if (...),当下面的公式k=0时就是f[i][j] = f[i-1][j]
f[i][j] = max(f[i][j], f[i - 1][j - v[i] * k] + w[i] * k);
}
cout << f[n][m] << endl;
return 0;
}
//优化空间后
// 时间复杂度为 O(N*V) 或 O(N*M) 或 O(N^2) 1e6次运算量
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m;
int v[N], w[N];
int f[N][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 = 0; j <= m; j ++) {
f[i][j] = f[i - 1][j];
if (j >= v[i]) f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
//上面两行不可以合并成if (j >= v[i]) f[i][j] = max(f[i - 1][j], f[i][j - v[i]] + w[i]); 因为选0个第i个物品的情况不需要j>=v[i]的条件
}
cout << f[n][m] << endl;
return 0;
}
//再次优化空间后(从f[i][j]二维变成一维f[j])
// 时间复杂度为 O(N*V) 或 O(N*M) 或 O(N^2) 1e6次运算量
#include <iostream>
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 ++) { //与01背包问题只有这里不一样,其余都一样,01背包循环体积时,从大到小循环j--,完全背包从小到大循环j++
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
cout << f[m] << endl;
return 0;
}
图一:
图二: