python多重背包_多重背包问题 I

最佳答案

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值