第九章 動態規劃-1272:【例9.16】分組揹包

1272:【例9.16】分組揹包

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 3671 通過數: 2324
【題目描述】
一個旅行者有一個最多能裝V公斤的揹包,現在有n件物品,它們的重量分別是W1,W2,…,Wn,它們的價值分別爲C1,C2,…,Cn。這些物品被劃分爲若干組,每組中的物品互相沖突,最多選一件。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

【輸入】
第一行:三個整數,V(揹包容量,V≤200),N(物品數量,N≤30)和T(最大組號,T≤10);

第2…N+1行:每行三個整數Wi,Ci,P,表示每個物品的重量,價值,所屬組號。

【輸出】
僅一行,一個數,表示最大總價值。

【輸入樣例】
10 6 3
2 1 1
3 3 1
4 8 2
6 9 2
2 8 3
3 9 3
【輸出樣例】
20


思路:分組的揹包問題首先判斷一個分組當中的一件物品,同01揹包一樣,此物品存在兩種狀態,取與不取,若取此物品,則繼續判斷下一組的第一件物品,若不取此物品,則繼續判斷本組下一件物品,若該物品爲本組最後一件物品,則判斷下一組。也就是說設f[k][v]表示前k組物品花費費用v能取得的最大權值,則有:f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i]|物品i屬於組k}。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define M 1005
using namespace std;
int W,T,N,i,j,k;
int w[M],c[M],p,dp[M];
int group[M][M];
int main()
{
	cin >> W >> N >>T;
	memset(dp,0,sizeof(dp));
	memset(group,0,sizeof(group));
	for(i = 1; i <= N;i++)
	{
		cin >> w[i] >> c[i] >> p ;
		group[p][++group[p][0]] = i;
		
	}
	for(i = 1 ; i <= T;i++)//第一層遍歷的是組數
	{
		for(j = W; j >= 0; j--)//第二層遍歷的是價值(倒序)
		{
			for(k = 1; k <= group[i][0];k++)//第三層遍歷的是每一組的物品。
			{
				int q = group[i][k];//q爲第幾個物品 
				if(j >= w[q])
				dp[j] = max(dp[j],dp[j-w[q]]+c[q]);
			}
			
		}
	}
	printf("%d\n",dp[W]);
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章