基础背包问题整理

有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。
求解将哪些物品装入背包可使价值总和最大。
初始化:
1、如果背包要求正好装满则初始化 f[0] = 0, f[1~V] = -INF;
2、如果不需要正好装满 f[0~v] = 0;
3、最后f[V]>0就说明可以装满

int N, V,  c[MAXN],  w[MAXN],  f[MAXN];  //f[i]当空间为i的时候的最大值 

目录

  • 01背包
  • 分组背包
  • 完全背包
  • 多重背包
  • 二维费用背包

01背包

每种物品仅有一件,可以选择放或不放

int F() {
	memset(f, 0, sizeof(f));  
	for(int i = 1; i <= N; i++)  
		for(int j = V; j >= c[i]; j--)  
			f[j] = max(f[j], f[j-c[i]] + w[i]);
	return f[V];
}

分组背包

每组最多只能取一件

int F() {//G分组的数量, g[i]第i组的物品数量 
	memset(f, 0, sizeof(f));  
	for(int i = 1; i <= G; i++)  
		for(int j = V; j >= 1; j--) 
			for(int k = 1; k <= g[i]; k++)  
				if(j >= c[i][k]) f[j] = max(f[j-c[i][k]] + w[i][k], f[j]);
	return f[V];	
}

完全背包

每种物品可以放无限多次

int F() {
	memset(f, 0, sizeof(f));
    for(int i =1 ; i <= N ; i++)  
    	for(int j = c[i]; j <= V; j++)  
    		f[j] = max(f[j], f[j-c[i]]+w[i]);
    return f[V];
}

多重背包

每种物品有一个固定的次数上限n[i]

Void F() {  
    memset(f, 0, sizeof(f));  
    for(int i = 1; i <= N ; i++) 
    	for(int k = 1; k <= n[i] ; k++)  
            for(int j = V ; j >= c[i]; j--)  
            	f[j] = max( f[j], f[j-c[i]]+w[i] );  
    return f[V];
} 

二维费用背包

每种物品的消耗有两个c1和c2,总容量也有两个V1,V2

int F() {
	memset(f, 0, sizeof(f));
    for(int i =1 ; i <= N ; i++)  
    	for(int j = V1; j >= c1[i]; j--)
    		for(int k = V2; k >= c2[i]; k--)  
    			f[j][k] = max(f[j][k], f[j-c1[i]][k-c2[i]] + w[i]);
    return f[V1][V2];
}
/* 如果背包要求正好装满,则初始化
for(int i = 0; i <= V1; i++)
	for(int j = 0; j <= V2; j++) 
		f[i][j] = -INF;    
f[0][0] = 0;
*/

你可能感兴趣的:(算法)