分组背包分组背包 分 组 背 包
Description
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
Input
第一行:三个整数,v(背包容量,v<=200),n(物品数量,n<=30)和t(最大组号,t<=10);
第2…n+1行:每行三个整数wi,ci,p,表示每个物品的重量、价值、所属组号。
Output
仅一行,一个数,表示最大总价值。
Sample Input
10 6 3
2 1 1
3 3 1
4 8 2
6 9 2
2 8 3
3 9 3
Sample Output
20
题目大意:
有一个背包,有他的可承受重量,现在有一些房间,每个房间只能拿一个物品来放在背包里,背包在不超重的情况下,价值最大是多少
解题思路:
按01背包的方法写,再在里面加一个循环,用于枚举第几件,然后记住枚举重量时要倒着
动态转移方程
f[j]=max(f[j],f[j−v[i][k]]+a[i][k]);f[j]=max(f[j],f[j-v[i][k]]+a[i][k]); f [ j ] = m a x ( f [ j ] , f [ j − v [ i ] [ k ] ] + a [ i ] [ k ] ) ;
#include <cstdio>
#include <iostream>
using namespace std;
int a[ 15 ] [ 30 ] , v[ 15 ] [ 30 ] , b[ 15 ] , f[ 205 ] , n, t, m, x, y, h;
int main ( )
{ scanf ( "%d%d%d" , & m, & n, & t) ; for ( int i= 1 ; i<= n; i++ ) { scanf ( "%d%d%d" , & x, & y, & h) ; v[ h] [ ++ b[ h] ] = x; a[ h] [ b[ h] ] = y; } for ( int i= 1 ; i<= t; i++ ) for ( int j= m; j> 0 ; j-- ) for ( int k= 1 ; k<= b[ i] ; k++ ) if ( j>= v[ i] [ k] ) f[ j] = max ( f[ j] , f[ j- v[ i] [ k] ] + a[ i] [ k] ) ; printf ( "%d" , f[ m] ) ;
}