庆功会 https://www.acwing.com/problem/content/1021/
朴素版一/二维写法 + 二进制优化版
#include <iostream>
using namespace std;
const int N = 6010;
int f[N][N], v[N], w[N], s[N], n, m;
int main()
{
cin >> n >> m;
for ( int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i] >> s[i];
for ( int i = 1; i <= n; i ++ )
for ( int j = 0; j <= m; j ++ )
for ( int k = 0; k <= s[i] && k * v[i] <= j; k ++)
f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);
cout << f[n][m];
return 0;
}
一维写法
#include <iostream>
using namespace std;
const int N = 6010;
int f[N], n, m;
int main()
{
cin >> n >> m;
for ( int i = 1; i <= n; i ++ )
{
int v, w, s;
cin >> v >> w >> s;
for ( int j = m; j >= 0; j -- ) //从大到小
for ( int k = 0; k <= s && k * v <= j; k ++ )
f[j] = max(f[j], f[j - k * v] + w * k);
}
cout << f[m];
return 0;
}
二进制优化
#include <iostream>
using namespace std;
const int N = 5010, M = 6010;
int f[M], v[N], w[N];
int n, m, p;
int main()
{
cin >> n >> m;
while ( n -- )
{
int a, b, s, k = 1;
cin >> a >> b >> s;
while ( k <= s )
{
v[++ p] = k * a;
w[p] = k * b;
s -= k;
k *= 2;
}
if ( s > 0 )
{
v[++ p] = s * a;
w[p] = s * b;
}
}
for ( int i = 1; i <= p; i ++ )
for ( int j = m; j >= v[i]; j -- )
f[j] = max(f[j], f[j - v[i]] + w[i]);
cout << f[m];
return 0;
}