Q1: 采药
思路分析:
01 背包裸题,此处的总时间
T
T
T 即是01 背包问题中的总体积,采摘某株草药的时间和这株草药的价值分别对应01 背包问题中的物品体积和物品收益。
参考代码:
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
const int N = 105, M = 1005;
int n, m;
int v[N], w[N], f[M];
inline void slove()
{
cin >> m >> n;
for(int i = 1; i <= n; ++ i)
cin >> v[i] >> w[i];
for(int i = 1; i <= n; ++ i)
for(int j = m; j >= v[i]; -- j)
f[j] = max(f[j], f[j - v[i]] + w[i]);
cout << f[m] ;
}
int main()
{
IO;
int _;
_ = 1;
//cin >> _;
while(_ --)
{
slove();
}
return 0;
}
Q2: 装箱问题
思路分析:
本题要求箱子最小剩余空间,那么我们可以通过求解最多能用完箱子多少空间,从而翻过求解箱子最小剩余空间。我们使用
f
[
N
]
f[N]
f[N] 来表示各种状态,
f
[
j
]
f[j]
f[j] 表示用了的空间为
j
j
j 且
f
[
j
]
f[j]
f[j] 的值为
t
r
u
e
true
true 时,表示可以使用到
j
j
j 个空间,反之则不能。接下来我们考虑状态之间是如何转移的,显然
f
[
j
]
f[j]
f[j] 是从
f
[
j
−
v
[
i
]
]
f[j - v[i]]
f[j−v[i]] 状态转移过来,当
f
[
j
−
v
[
i
]
]
f[j - v[i]]
f[j−v[i]] 为
t
r
u
e
true
true 时,那么
f
[
j
]
f[j]
f[j] 就是
t
r
u
e
true
true,当
f
[
j
−
v
[
i
]
]
f[j - v[i]]
f[j−v[i]] 为
f
a
l
s
e
false
false 时,那么
f
[
j
]
f[j]
f[j] 就是
f
a
l
s
e
false
false。所以我们得到状态转移方程:
f[j] |= f[j - v[i]];
参考代码:
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
const int N = 35, M = 2e4 + 5;
int n, m, v[N];
bool f[M];
inline void slove()
{
cin >> m >> n;
for(int i = 1; i <= n; ++ i)
cin >> v[i] ;
f[0] = true;
for(int i = 1; i <= n; ++ i)
for(int j = m; j >= v[i]; -- j)
f[j] |= f[j - v[i]];
int i;
for(i = m; !f[i]; -- i) ;
cout << m - i ;
}
int main()
{
IO;
int _;
_ = 1;
//cin >> _;
while(_ --)
{
slove();
}
return 0;
}
Q3: 开心的金明
思路分析:
01 背包裸题,此处的总钱数即是01 背包问题中的总体积,物品的价格vi,重要度与价格的乘积 vi * wi 分别对应01 背包问题中的物品体积和物品收益。
参考代码:
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
const int N = 30, M = 30005;
int n, m;
int v[N], w[N], f[M];
inline void slove()
{
cin >> m >> n;
for(int i = 1; i <= n; ++ i)
{
int p;
cin >> v[i] >> p;
w[i] = v[i] * p;
}
for(int i = 1; i <= n; ++ i)
for(int j = m; j >= v[i]; -- j)
f[j] = max(f[j], f[j - v[i]] + w[i]);
cout << f[m] ;
}
int main()
{
IO;
int _;
_ = 1;
//cin >> _;
while(_ --)
{
slove();
}
return 0;
}
End:
今天的题解分享就到这里结束啦,如果有更好的解法或者思路,欢迎大家评论区留言交流!!!