题解-分组背包

标题 分组背包

Description

一个旅行者有一个最多能装V公斤的背包,现在有n件物品,它们的重量分别是W_1,W_2,…,W_n,它们的价值分别为C_1,C_2,…,C_n 。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
Input
第一行:三个整数,V(背包容量,V≤200),N(物品数量,N≤30)和T(最大组号,T≤10);
第2…N+1行:每行三个整数Wi,Ci,P,表示每个物品的重量,价值,所属组号。
Output
仅一行,一个数,表示最大总价值。
Sample Input 1
10 6 3
2 1 1
3 3 1
4 8 2
6 9 2
2 8 3
3 9 3
Sample Output 1
20
提示:输入时开一个二维数组p[1000][1000],用所属组号X来表示p[x][0]++,在代入p[x][]里面,赋值为i,GAME OVER.
解析:这道题与01背包和完全背包很像,开三个一维数组,在用一个二维数组来计数。先来两层for循环(跟01背包一样),再开一层k的循环,k用来统计物品的次数,也就是k<=p[i][0]时。然后,我们来判断是否大于背包容量,能就执行。最后的就不多多讲了(本君特懒),按照01背包的写法,来扩展一下:
dp[j]=max(dp[j],dp[j-w[p[i][k]]]+q[p[i][k]]);
这是方程,就是(01背包不用解释)把他们的多余的那一份舍去,在把得到的加上。如图:
题解-分组背包_第1张图片
代码:

#include
using namespace std;
int w[10000],q[10000],p[1000][1000],dp[10000];
int main(){
	int s;
	int v,n,t;
	cin>>v>>n>>t;
	for(int i=1;i<=n;i++){
		cin>>w[i]>>q[i]>>s; 
		p[s][0]++;
		p[s][p[s][0]]=i;
	}
	for(int i=1;i<=t;i++){
		for(int j=v;j>=0;j--){
			for(int k=1;k<=p[i][0];k++){
				if(j>=w[p[i][k]]){
					dp[j]=max(dp[j],dp[j-w[p[i][k]]]+q[p[i][k]]);
				}
			}
		}
	}
	cout<

关注一下呗

你可能感兴趣的:(题解)