分组背包
分组背包
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;
}

浙公网安备 33010602011771号