Multiple knapsack problem 1

Multiple knapsack problem 1


from acwing 4
Time limit: 1s
Space limitation: 64MB

Title description:

There are N items and a backpack with a capacity of V.

The i-th item has at most si items, each of which has a volume of vi and a value of wi.

Solve which items are loaded into the backpack, so that the total volume of the items does not exceed the capacity of the backpack, and the total value is the largest.
Output the maximum value.

Input format:

The two integers in the first line, N and V, are separated by a space, indicating the number of objects and the volume of the backpack, respectively.

Next, there are N rows, each with three integers vi, wi, si, separated by spaces, indicating the volume, value, and quantity of the i-th item.

Output format:

Output an integer that represents the maximum value.

data range:

0 < N,V <= 100

0 < vi,wi,si <= 100

Input sample:

4 5
1 2 3
2 4 1
3 4 3
4 5 2

Sample output:

10

This problem can be completed with a dp two-dimensional array, but if optimization is performed, the array can be opened into a one-dimensional array, and for each product operation, it is enough to refresh the backpack from back to front.

On the basis of the 01 backpack, there may be multiple items for each product on this topic. For example, if there are three such products, we will treat them as three different products and use the 01 backpack method.

01 backpack problem

One-dimensional:
#include<iostream>
using namespace std;
int N,V,dp[105];           //dp是状态数组,表示背包在某个容量目前能装下的最多价值
int main(){
    
    
    cin>>N>>V;
    for(int i = 1;i <= N;++i){
    
    
        int a,b,c;cin>>a>>b>>c;  //商品的体积和价值
        while(c--)
            for(int j = V;j >= a;--j)
                if(dp[j] < dp[j - a] + b)   //如果在此时装入该物品,价值会提升,那么就装入
                    dp[j] = dp[j - a] + b;
    }
    cout<<dp[V];
    return 0;
}
Two-dimensional:
#include<iostream>
#include<algorithm>
using namespace std;
int vi[10005];
int wi[10005];
int dp[10005][105];
int main(){
    
    
	int n,v,k = 0,a,b,c;
	cin>>n>>v;
	for(int i = 1;i <= n;i++){
    
    
		cin>>a>>b>>c;
		while(c--){
    
    
			vi[++k] = a;
			wi[k] = b;
		}
	}
	n = k;
	for(int i = 1; i <= n;i++)
		for(int j = 1;j <= v;j++){
    
    
			if(j < vi[i])
				dp[i][j] = dp[i - 1][j];
			else{
    
    
				dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - vi[i]] + wi[i]);
			}
		}
	cout<<dp[n][v];
	return 0;
} 

Guess you like

Origin blog.csdn.net/qq_45985728/article/details/113596954