携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情
通天之分组背包
题目背景
直达通天路·小 A 历险记第二篇
题目描述
自 背包问世之后,小 A 对此深感兴趣。一天,小 A 去远游,却发现他的背包不同于 背包,他的物品大致可分为 组,每组中的物品相互冲突,现在,他想知道最大的利用价值是多少。
输入格式
两个数 ,表示一共有 件物品,总重量为 。
接下来 行,每行 个数 ,表示物品的重量,利用价值,所属组数。
输出格式
一个数,最大的利用价值。
样例 #1
样例输入 #1
45 3
10 10 1
10 5 1
50 400 2
样例输出 #1
10
提示
。
v[i]是重量,V是总重量,f是前i个j重量的价值,w是每个的价值
for(int i=1;i<=m;i++)
for(int k=v[i];k<=V;k++)
for(int j=0;j<=n[i];j++)
f[i][k]=max(f[i][k],f[i-1][j-v[i][j]]+w[i][j]);
代码如下
#include<iostream>
#include<cstdio>
using namespace std;
int c[1005],f[1005][1005],a[1005][1005],d[1005][1005];
int main()
{
int n,m,mq=0;
cin>>m>>n;
for(int i=1;i<=n;i++)
{
int o,p,q;//o 是 物品重量,p是利用价值,q是组
cin>>o>>p>>q;
if(mq<q) mq=q;//找出最大组,即共有多少个组
c[q]++;//每个组的第几个元素
d[q][c[q]]=o;//q 组的c[q]个元素的重量是 o
a[q][c[q]]=p;
}
for(int i=1;i<=mq;i++)//mq是共有多少个组
{
for(int k=1;k<=c[i];k++)//k是组里的元素
{
for(int j=m;j>=d[i][j];j--)//一定要从大到小,避免一个元素多次用
{
if(j-d[i][k]>=0)
f[i][j]=max(f[i][j],f[i-1][m-j]+a[i][k]);//f是前i个数j重量的价值
}
}
}
int maxx=0;
for(int i=1;i<=mq;i++)//找出最大
{
for(int j=1;j<=m;j++)
{
if(f[i][j]>maxx) maxx=f[i][j];
}
}
cout<<maxx;
}