分組揹包【DP】
阿新 • • 發佈:2018-12-16
> 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
>解題思路
這一題分組揹包,有很多個條件:每組只能選一個或是選擇不選,物品總重量不能超過揹包總重量v,求出最大價值。
f[i][j]表示前i組總重量為j的最大價值。首先我輸入時就把每一組每一組地分了出來,然後最外層迴圈前k組,然後是用的重量i,再是迴圈第k組的每一個選項
狀態轉移方程:
f[i][j]=max(f[i][j],f[i-1][j-w[i]]+c[i])
還是挺簡單的
>程式碼
#include<iostream>
#include<cstdio>
using namespace std;
int v,n,t,w[15][35],c[15][35],f[15][205];
int main()
{
int x,y,s;
scanf("%d%d%d",&v,&n,&t);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&s);
w[s][++w[s][0]]=x; c[s][++c[s][0]]=y;
//存每一組
}
for(int k=1;k<=t;k++) //迴圈前k組
for(int i=1;i<=v;i++) //重量
{
f[k][i]= f[k-1][i]; //這個不用解釋了吧
for(int j=1;j<=w[k][0];j++) //每一項
if(i-w[k][j]>=0) //防止越界
f[k][i]=max(f[k][i],f[k-1][i-w[k][j]]+c[k][j]);
}
printf("%d",f[t][v]);
return 0;
}