Mixed knapsack problem, two-dimensional cost knapsack problem, group knapsack problem

Yan Shen video notes

Video link

The mixed backpack problem is the combination of 01 backpack, complete backpack, and multiple backpacks.

Mixed knapsack problem ( topic link )

Problem-solving ideas:

You can first convert the multiple knapsacks part into the 01 knapsack problem by binary optimization, and finally the 01 knapsack and the complete knapsack are left, and the difference between the two calculations is the order of the loop, one forward and one backward, so just in the loop Just judge it when

Code:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
using namespace std;
const int N = 1010;
int n,m,v,w,s,f[N];
struct Good{
    
    
	int type,v,w;
}; 
vector<Good>goods;
int main(){
    
    
//	freopen("1.txt","r",stdin);
	cin>>n>>m;
	for(int i=0;i<n;i++){
    
    
		cin>>v>>w>>s;
		if(s<0) goods.push_back({
    
    -1,v,w});
		else if(s==0) goods.push_back({
    
    0,v,w});
		else{
    
    
			for(int j=1;j<=s;j*=2){
    
    
				s-=j;
				goods.push_back({
    
    -1,v*j,w*j});
			}
			if(s>0) goods.push_back({
    
    -1,v*s,w*s}); 
		}
	}
	for(auto good:goods){
    
    
		if(good.type==-1){
    
    
			for(int i=m;i>=good.v;i--) f[i] = max(f[i],f[i-good.v]+good.w);
		}else{
    
    
			for(int i=good.v;i<=m;i++) f[i] = max(f[i],f[i-good.v]+good.w);
		}
	}
	cout<<f[m]<<endl;
	return 0;
}

Two-dimensional cost knapsack problem ( topic link )

Problem-solving ideas:

The backpack problem of the two-dimensional cost is an upgraded version of the 01 backpack. In addition to the size and weight of the backpack and items. The idea to solve the problem is to upgrade the original one-dimensional array to a two-dimensional array. In this way, f[i][j] represents the optimal solution with volume i and weight j, and just one more cycle in the calculation process.

Code:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
using namespace std;
const int N = 1010;
int n,V,M,v,m,w,f[N][N]; 
int main(){
    
    
//	freopen("1.txt","r",stdin);
	cin>>n>>V>>M;
	for(int i=0;i<n;i++){
    
    
		cin>>v>>m>>w;
		for(int j=V;j>=v;j--){
    
    
			for(int k=M;k>=m;k--){
    
    
				f[j][k] = max(f[j][k],f[j-v][k-m]+w);
			}
		}
	}
	cout<<f[V][M]<<endl;
	return 0;
}

Group knapsack problem ( topic link )

Problem-solving ideas:

The problem of group knapsack is that each item has a group, and each group can only select one item at most. It is a variant of 01 backpack. The idea is to traverse all the items in a group once (that is, there are onlyselectedwithUncheckTwo options, now there are s+1 options,NoneorChoose the first itemorChoose the second item…)

Code 1 (mine):

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
using namespace std;
const int N = 110;
int n,m,k,v,w,f[N],g[N];
int main(){
    
    
//	freopen("1.txt","r",stdin);
	cin>>n>>m;
	for(int i=0;i<n;i++){
    
    
		cin>>k;
		memcpy(g,f,sizeof f);
		for(int ii=0;ii<k;ii++){
    
    
			cin>>v>>w;
			for(int j=m;j>=v;j--){
    
    
				f[j] = max(f[j],g[j-v]+w);
			}
		} 
	}
	cout<<f[m]<<endl;
	return 0;
}

Code 2 (big guy's):

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
using namespace std;
const int N = 110;
int n,m,s,v[N],w[N],f[N];
int main(){
    
    
//	freopen("1.txt","r",stdin);
	cin>>n>>m;
	for(int i=0;i<n;i++){
    
    
		cin>>s;
		for(int j=0;j<s;j++){
    
    
			cin>>v[j]>>w[j];
		} 
		for(int j=m;j>=0;j--){
    
    
			for(int k=0;k<s;k++){
    
    
				if(j-v[k]>=0) f[j] = max(f[j],f[j-v[k]]+w[k]);
			}
		}
	}
	cout<<f[m]<<endl;
	return 0;
}

Guess you like

Origin blog.csdn.net/lmmmmmmmmmmmmmmm/article/details/107330847