分組揹包
其實也不難,弄清楚01揹包就十分好解決了!
題目描述:
有N件物品,告訴你這N件物品的重量以及價值,將這些物品劃分爲K組,每組中的物品互相沖突,最多選一件,求解將哪些物品裝入揹包可使這些物品的費用綜合不超過揹包的容量,且價值總和最大。
算法分析:
首先判斷一個分組當中的一件物品,同01揹包一樣,此物品存在兩種狀態,取與不取,若取此物品,則繼續判斷下一組的第一件物品,若不取此物品,則繼續判斷本組下一件物品,若該物品爲本組最後一件物品,則判斷下一組。也就是說設f[k][v]表示前k組物品花費費用v能取得的最大價值。
二維:
f[i][C]=max{f[i-1][C],f[i-1][C-w[x]]+v[x]
{物品x屬於組i}。
一維
f[C]=max{f[C],f[C-w[x]]+v[x]
{物品x屬於組i}。
使用一維數組的僞代碼如下:
for 所有的組k
for v=V..0
for 所有的i屬於組k
f[v]=max{f[v],f[v-c[i]]+w[i]}
對於這種揹包,我採用了vector(動態數組)。不懂戳這裏
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e3+10;
vector<int>a[N];
int n,C,w[N],v[N],f[N],cnt,maxgroup;
int main()
{
//fre();
scanf("%d%d",&C,&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&w[i],&v[i],&cnt);
maxgroup=max(maxgroup,cnt);
a[cnt].push_back(i);
}
for(int i=1;i<=maxgroup;i++)
{
for(int j=C;j>=0;j--)
{
for(int k=0;k<a[i].size();k++)
{
int x=a[i][k];
if(j>=w[x]) f[j]=max(f[j],f[j-w[x]]+v[x]);
}
}
}
printf("%d",f[C]);
return 0;
}