最佳答案
AcWing 4. 多重背包问题 I
#include
#include
using namespace std;
const int N=110;
int n,m;
int f[N][N];
int v[N],w[N],s[N];
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<
return 0;
}
发布于 2020-02-16
最佳答案
AcWing 4. 多重背包问题 I java
样例
import java.util.Scanner;
/**
* Description:第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
* 接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。
* 题目地址:https://www.acwing.com/problem/content/4/
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int N = sc.nextInt();
int V = sc.nextInt();
int v[] = new int[N + 1];
int w[] = new int[N + 1];
int s[] = new int[N + 1];
int f[][] = new int[N + 1][V + 1];
for (int i = 1; i < N + 1; i++) {
v[i] = sc.nextInt();
w[i] = sc.nextInt();
s[i] = sc.nextInt();
}
for (int i = 1; i <= N; i++) {
for (int j = V; j >= 0; j--) {
for (int k = 0; k <= s[i]; k++) {
if (j >= k * v[i]) {
f[i][j] = Math.max(f[i][j], f[i - 1][j - k * v[i]] + k * w[i]);
}
}
}
}
System.out.println(f[N][V]);
}
}
}
发布于 2020-02-16
最佳答案
AcWing 4. 【Java】多重背包问题 I
/*
1. 状态定义: 已经选了1...i种物品且背包体积 <=j 时的最大值 -> 优化为f[j]
2. 状态计算: 以最后一次选i划分为选还是不选,根据遍历体积转化为选几次 即 f[j] = MAX (f[j - k* v[i]] + k*w[i] )
3. 边界:f[~] = 0
*/
import java.util.*;
public class Main{
void run(){
int n = jin.nextInt();
int m = jin.nextInt();
for (int i = 1 ; i <= n ; i++) {
v[i] = jin.nextInt();
w[i] = jin.nextInt();
s[i] = jin.nextInt();
}
int res = dp(n, m);
System.out.println(res);
}
int dp(int n, int m){
int[] f = new int[maxN];
for (int i = 1 ; i <= n ;i ++){
for (int j = m ; j >= v[i] ; j--){
for (int k = 0 ; k <= s[i] && k* v[i] <= j ;k++){
// 把最简单的完全背包改写下
f[j] = Math.max(f[j], f[j - k* v[i]] + k* w[i]);
}
}
}
return f[m];
}
int maxN = 1002;
int[] v = new int[maxN];
int[] w = new int[maxN];
int[] s = new int[maxN];
Scanner jin = new Scanner(System.in);
public static void main(String[] args) {new Main().run();}
}
发布于 2020-02-16
最佳答案
AcWing 4. 多重背包问题 I
有 N种物品和一个容量是 V 的背包,每种物品都有无限件可用。
第 ii 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 N 行,每行两个整数 vi, wi,si 用空格隔开,分别表示第 i 件物品的体积和价值和数量。
输出格式
输出一个整数,表示最大价值。
数据范围
0
0
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例
10
基本思考框架
这个其实和多重背包很类似,具体原理在之前有关动态规划的博客,已经讲得很详细了,直接看代码吧:
C++ 代码
#include
using namespace std;
const int N = 110;
int f[N][N];
int v[N],w[N];
int main()
{
int n,m,v,w,s;
cin>>n>>m;
for(int i = 1 ; i <= n ; i++)
{
//在线做法
cin>>v>>w>>s;
for(int j = 0 ; j <= m ; j++)
{
for(int k = 0 ; k*v<=j&&k <= s ;k ++)
f[i][j]=max(f[i][j],f[i-1][j-k*v]+k*w);
}
}
cout<
}
发布于 2020-02-16
最佳答案
AcWing 4. 多重背包问题 I
include[HTML_REMOVED]
using namespace std;
const int N = 1005;
int w[N], v[N], s[N], f[N], n, m;
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i)
cin >> w[i] >> v[i] >> s[i];
for(int i = 1; i <= n;i)
for(int j = m; j >= 0; –j)
for(int k = 1; k <= s[i]; ++k)
if(j >= k * w[i])
f[j] = max(f[j], f[j - k * w[i]] + k * v[i]);
cout << f[m] << endl;
return 0;
}
发布于 2020-02-16
最佳答案
AcWing 4. 多重背包问题 I c++
和01背包一样,不过遍历c遍而已
C++ 代码
#include
using namespace std;
int dp[1005];
int main()
{
int n,m,a,b,c;
cin >> n >> m;
for(int i=0;i
cin >> a >> b >> c;
for(int i=1;i<=c;++i){ //c遍 01背包就可以了
for(int j=m;j>=a*i;--j){
dp[j]=max(dp[j],dp[j-a]+b);
}
}
}
cout << dp[m];
return 0;
}
还有一种非二进制、非单调队列的优化代码,完全可以通过多重背包问题II和III,
我放在这里了 链接 (https://www.acwing.com/solution/acwing/content/4940/)
发布于 2020-02-16
最佳答案
AcWing 4. 多重背包问题 I(python3代码)
转换为01背包
n,v = map(int, input().split())
goods = []
for i in range(n):
goods.append([int(i) for i in input().split()])
new_goods = []
for i in range(n):
for j in range(goods[i][2]):
new_goods.append(goods[i][0:2])
goods = new_goods
n = len(goods)
dp = [0 for i in range(v+1)]
for i in range(n):
for j in range(v,-1,-1):
if j>= goods[i][0]:
dp[j] = max(dp[j], dp[j - goods[i][0]] + goods[i][1])
print(dp[-1])
一维动态规划
n,v = map(int, input().split())
goods = []
for i in range(n):
goods.append([int(i) for i in input().split()])
dp = [0 for i in range(v+1)]
for i in range(n):
for j in range(v, -1, -1):
# 考虑两种情况的最小值
k = min(j//goods[i][0], goods[i][2])
dp[j] = max([dp[j-x*goods[i][0]] + x*goods[i][1] for x in range(k+1)])
print(dp[-1])
发布于 2020-02-16
最佳答案
AcWing 4. 多重背包问题 I-python解答
n, v = map(int, input().split())
f = [0 for _ in range(v+1)]
for i in range(n):
b, w, s = map(int, input().split())
for j in range(v, -1, -1):
k = 1
while k <= s and j >= k * b:
f[j] = max(f[j], f[j - k*b] + k*w)
k += 1
print(f[v])
发布于 2020-02-16
最佳答案
AcWing 4. 多重背包问题 I
题目描述
多重背包
code
#include
const int maxn = 150;
template
inline void read(T &s) {
s = 0;
T w = 1, ch = getchar();
while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); }
s *= w;
}
int n;
int m;
int s[maxn];
int v[maxn];
int w[maxn];
int f[maxn];
int main() {
read(n), read(m);
for (int i = 1; i <= n; ++i) {
read(w[i]);
read(v[i]);
read(s[i]);
}
f[0] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = m; j >= w[i]; --j) {
for (int k = 1; k <= s[i] && k * w[i] <= j; ++k) {
f[j] = std::max(f[j], f[j - k * w[i]] + k * v[i]);
// printf()
}
}
}
printf("%d\n", f[m]);
return 0;
}
发布于 2020-02-16
最佳答案
AcWing 4. 多重背包问题 I
可以当成完全背包来做吧
#include
using namespace std;
typedef long long ll;
const int N=1005;
int a[N],b[N],d[N],c[N];
int n,v;
int main(){
cin>>n>>v;
for(int i=0;i
cin>>a[i]>>b[i]>>c[i];
for(int i=0;i
for(int j=v;j>=0;j--){
int t=v/a[i];
for(int k=1;k<=min(t,c[i]);k++)
if(j>=k*a[i])
d[j]=max(d[j],d[j-k*a[i]]+k*b[i]);
}
cout<
return 0;
}
发布于 2020-02-16