进阶动态规划,对应蓝桥云课小明的背包3 代码框架见下
cpp
#include <iostream>
using namespace std;
#define maxn 101
#define maxc 10
#define maxv 201
#define inf -1
#define init 0
#define vType int
vType opt(int a, int b){
if(a == inf) return b;
if(b == inf) return a;
return a > b ? a : b;
}
void Knapsack01(int n, int V, int w[maxn*maxc], vType v[maxn*maxc], vType dp[maxv]){
// 1 初始化
for(int i=1; i <= V; ++i){
dp[i] = inf;
}
dp[0] = init;
// 2 状态转移
for(int i=1; i<=n; ++i){
for(int j=V; j >= w[i]; --j){
dp[j] = opt(dp[j], dp[j - w[i]] + v[i]);
}
}
}
void knapsackMultiple(int n, int V, int w[maxn], vType v[maxn], int c[maxn], vType dp[maxv]){
int m=0; // 拆分以后,物品数量就是m了,不再是n
int nw[maxn * maxc];
vType nv[maxn * maxc];
for(int i=1; i <= n; ++i){
int k = 1;
while(k < c[i]){
++m;
nw[m] = k*w[i];
nv[m] = k*v[i];
c[i] -= k;
k *= 2;
}
if(c[i]){
++m;
nw[m] = c[i]*w[i];
nv[m] = c[i]*v[i];
}
}
Knapsack01(m, V, nw, nv, dp);
}
int w[maxn], c[maxn];
vType v[maxn];
vType dp[maxv];
int main()
{
int n, V;
cin >> n >> V;
for(int i=1; i<=n; ++i){
cin >> w[i] >> v[i] >> c[i];
}
knapsackMultiple(n, V, w, v, c, dp);
vType ret = 0;
for(int i=0; i <= V; ++i){
ret = opt(ret, dp[i]);
}
cout << ret << endl;
// 请在此输入您的代码
return 0;
}
代码练习 1 对应蓝桥云课 小明的背包4 代码见下
cpp
#include <iostream>
using namespace std;
#define maxn 1001
#define maxc 10
#define maxv 2001
#define inf -1
#define init 0
#define vType int
vType opt(int a, int b){
if(a == inf) return b;
if(b == inf) return a;
return a > b ? a : b;
}
void Knapsack01(int n, int V, int w[maxn*maxc], vType v[maxn*maxc], vType dp[maxv]){
// 1 初始化
for(int i=1; i <= V; ++i){
dp[i] = inf;
}
dp[0] = init;
// 2 状态转移
for(int i=1; i<=n; ++i){
for(int j=V; j >= w[i]; --j){
dp[j] = opt(dp[j], dp[j - w[i]] + v[i]);
}
}
}
void knapsackMultiple(int n, int V, int w[maxn], vType v[maxn], int c[maxn], vType dp[maxv]){
int m=0; // 拆分以后,物品数量就是m了,不再是n
int nw[maxn * maxc];
vType nv[maxn * maxc];
for(int i=1; i <= n; ++i){
int k = 1;
while(k < c[i]){
++m;
nw[m] = k*w[i];
nv[m] = k*v[i];
c[i] -= k;
k *= 2;
}
if(c[i]){
++m;
nw[m] = c[i]*w[i];
nv[m] = c[i]*v[i];
}
}
Knapsack01(m, V, nw, nv, dp);
}
int w[maxn], c[maxn];
vType v[maxn];
vType dp[maxv];
int main()
{
int n, V;
cin >> n >> V;
for(int i=1; i<=n; ++i){
cin >> w[i] >> v[i] >> c[i];
if(c[i] == 0) c[i] = 2000;
}
knapsackMultiple(n, V, w, v, c, dp);
vType ret = 0;
for(int i=0; i <= V; ++i){
ret = opt(ret, dp[i]);
}
cout << ret << endl;
// 请在此输入您的代码
return 0;
}
代码2 新一的宝藏搜寻加强版 对应蓝桥云课
cpp
#include <iostream>
using namespace std;
#define maxn 1001
#define maxc 15
#define maxv 201
#define inf -1
#define init 0
#define vType int
vType opt(int a, int b){
if(a == inf) return b;
if(b == inf) return a;
return a > b ? a : b;
}
void Knapsack01(int n, int V, int w[maxn*maxc], vType v[maxn*maxc], vType dp[maxv]){
// 1 初始化
for(int i=1; i <= V; ++i){
dp[i] = inf;
}
dp[0] = init;
// 2 状态转移
for(int i=1; i<=n; ++i){
for(int j=V; j >= w[i]; --j){
dp[j] = opt(dp[j], dp[j - w[i]] + v[i]);
}
}
}
void knapsackMultiple(int n, int V, int w[maxn], vType v[maxn], int c[maxn], vType dp[maxv]){
int m=0; // 拆分以后,物品数量就是m了,不再是n
int nw[maxn * maxc];
vType nv[maxn * maxc];
for(int i=1; i <= n; ++i){
int k = 1;
while(k < c[i]){
++m;
nw[m] = k*w[i];
nv[m] = k*v[i];
c[i] -= k;
k *= 2;
}
if(c[i]){
++m;
nw[m] = c[i]*w[i];
nv[m] = c[i]*v[i];
}
}
Knapsack01(m, V, nw, nv, dp);
}
int w[maxn], c[maxn];
vType v[maxn];
vType dp[maxv];
int main()
{
int n, V;
cin >> n >> V;
for(int i=1; i<=n; ++i){
cin >> w[i] >> v[i] >> c[i];
}
knapsackMultiple(n, V, w, v, c, dp);
vType ret = 0;
for(int i=0; i <= V; ++i){
ret = opt(ret, dp[i]);
}
cout << ret << endl;
// 请在此输入您的代码
return 0;
}
代码练习3 对应蓝桥云课 鲁邦的甜品店 代码见下
cpp
#include <iostream>
using namespace std;
#define maxn 101
#define maxc 10
#define maxv 201
#define inf -1
#define init 0
#define vType int
vType opt(int a, int b){
if(a == inf) return b;
if(b == inf) return a;
return a > b ? a : b;
}
void Knapsack01(int n, int V, int w[maxn*maxc], vType v[maxn*maxc], vType dp[maxv]){
// 1 初始化
for(int i=1; i <= V; ++i){
dp[i] = inf;
}
dp[0] = init;
// 2 状态转移
for(int i=1; i<=n; ++i){
for(int j=V; j >= w[i]; --j){
dp[j] = opt(dp[j], dp[j - w[i]] + v[i]);
}
}
}
void knapsackMultiple(int n, int V, int w[maxn], vType v[maxn], int c[maxn], vType dp[maxv]){
int m=0; // 拆分以后,物品数量就是m了,不再是n
int nw[maxn * maxc];
vType nv[maxn * maxc];
for(int i=1; i <= n; ++i){
int k = 1;
while(k < c[i]){
++m;
nw[m] = k*w[i];
nv[m] = k*v[i];
c[i] -= k;
k *= 2;
}
if(c[i]){
++m;
nw[m] = c[i]*w[i];
nv[m] = c[i]*v[i];
}
}
Knapsack01(m, V, nw, nv, dp);
}
int w[maxn], c[maxn];
vType v[maxn];
vType dp[maxv];
int main()
{
int V, n, c0, d0;
cin >> V >> n >> c0 >> d0;
w[1] = c0;
c[1] = V/c0;
v[1] = d0;
for(int i=2; i <= n+1; ++i){
int ai, bi, ci, di;
cin >> ai >> bi >> ci >> di;
w[i] = ci;
c[i] = ai / bi;
v[i] = di;
}
knapsackMultiple(n+1, V, w, v, c, dp);
vType ret = inf;
for(int i=0; i <= V; ++i){
ret = opt(ret, dp[i]);
}
cout << ret << endl;
}