Bone Collector HDU - 2602
涂奥最近迷上了吃鸡,房间有
n
n
n 个配件,每个配件有
c
(
c
≤
1
0
3
)
c(c \le 10^3)
c(c≤103) 的重量和
v
(
v
≤
1
0
3
)
v(v \le10^3)
v(v≤103) 的价值,哇,涂奥捡了一个
2
2
2 级包,容量为
s
s
s ,所以涂奥最多当多肥的快递员呢?
Input
输入的第一行是
T
T
T , 表示有一共要打
T
T
T 场比赛。
每组数据由三行组成。
第
1
1
1 行包含两个整数
n
n
n 和
s
s
s ,第
2
2
2 行包含
n
n
n 个整数,表示每一个配件的价值。第
3
3
3 行包含
n
n
n 个整数,表示每个配件的重量。
Output
对每一组数据,输出涂奥可以多肥。
Sample Input
1
10 10
1 3 5 7 9 11 13 15 17 19
19 17 15 13 11 9 7 5 3 1
Sample Output
51
知识点:
01背包。
有普通二维做法和一维做法。
Code:
二维数组 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示前 i i i 个物品最多装 j j j 重量时的最大价值。
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 1000 + 10;
int n, s;
int v[N], w[N];
int dp[N][N];
int main(int argc, char const *argv[])
{
IO;
int T;
cin >> T;
while (T--)
{
memset(dp, 0, sizeof(dp));
cin >> n >> s;
for (int i = 1; i <= n; i++)
cin >> v[i];
for (int i = 1; i <= n; i++)
cin >> w[i];
for (int i = 1; i <= n; i++)
for (int j = 0; j <= s; j++)
{
if (w[i] > j)
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
}
cout << dp[n][s] << endl;
}
return 0;
}
一维数组 d p [ i ] dp[i] dp[i] 表示最多装 i i i 重量物品的最大价值。
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
using namespace std;
const int mod = 1e9 + 7;
const int N = 1000 + 10;
int n, s;
int v[N], w[N];
int dp[N];
int main(int argc, char const *argv[])
{
IO;
int T;
cin >> T;
while (T--)
{
memset(dp, 0, sizeof(dp));
cin >> n >> s;
for (int i = 0; i < n; i++)
cin >> v[i];
for (int i = 0; i < n; i++)
cin >> w[i];
for (int i = 0; i < n; i++)
for (int j = s; j >= w[i]; j--) //注意 01背包第二维是倒序,为了不重复往背包里放物品
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
cout << dp[s] << endl;
}
return 0;
}