【动态规划】通天之分组背包

156 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第24天,点击查看活动详情

通天之分组背包

题目背景

直达通天路·小 A 历险记第二篇

题目描述

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

输入格式

两个数 m,nm,n,表示一共有 nn 件物品,总重量为 mm

接下来 nn 行,每行 33 个数 ai,bi,cia_i,b_i,c_i,表示物品的重量,利用价值,所属组数。

输出格式

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

样例 #1

样例输入 #1

45 3
10 10 1
10 5 1
50 400 2

样例输出 #1

10

提示

1m,n10001 \leq m, n \leq 1000

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;
}