头像

欢迎来到我的博客

分享题解与总结

分组背包

分组背包

vs01背包——分组背包有分组限制:每组只能选一件商品

P1757通天之分组背包

题目描述

\(01\) 背包问世之后,小 A 对此深感兴趣。一天,小 A 去远游,却发现他的背包不同于 \(01\) 背包,他的物品大致可分为 \(k\) 组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少。

输入格式

两个数 \(m,n\),表示一共有 \(n\) 件物品,背包能承受的最大重量为 \(m\)

接下来 \(n\) 行,每行 \(3\) 个数 \(a_i,b_i,c_i\),表示物品的重量,利用价值,所属组数。

输出格式

一个数,最大的利用价值。

输入输出样例

输入

45 3
10 10 1
10 5 1
50 400 2

输出

10

说明/提示

\(0 \leq m \leq 1000\)\(1 \leq n \leq 1000\)\(1\leq k\leq 100\)\(a_i, b_i, c_i\)int 范围内。

二维模板

struct item{
	int w,v;
};
vector<item> g[N];
int dp[N][M];
int n,m,a,b,c,k,sze,wgt,val;

int main()
{
	cin>>m>>n;
	for(int i=1;i<=n;++i){
		cin>>a>>b>>c;
		if(g[c].size()==0) k++;
		g[c].push_back({a,b});
	}
	for(int i=1;i<=k;++i){
		for(int j=1;j<=m;++j){
			dp[i][j]=dp[i-1][j];
			sze=g[i].size();
			for(int l=0;l<sze;++l){
				wgt=g[i][l].w;
				val=g[i][l].v;
				if(j>=wgt) dp[i][j]=max(dp[i][j],dp[i-1][j-wgt]+val);
			}
		}
	}
	cout<<dp[k][m];
	return 0;
} 

一维模版

struct item{
	int w,v;
};
vector<item> g[N];
int dp[M];
int n,m,a,b,c,k,sze,wgt,val;

int main()
{
	cin>>m>>n;
	for(int i=1;i<=n;++i){
		cin>>a>>b>>c;
		if(g[c].size()==0) k++;
		g[c].push_back({a,b});
	}
	for(int i=1;i<=k;++i){
		for(int j=m;j>=1;--j){
			sze=g[i].size();
			for(int l=0;l<sze;++l){
				wgt=g[i][l].w;
				val=g[i][l].v;
				if(j>=wgt) dp[j]=max(dp[j],dp[j-wgt]+val);
			}
		}
	}
	cout<<dp[m];
	return 0;
} 
posted @ 2026-06-05 14:30  king_steph1209  阅读(17)  评论(0)    收藏  举报