1. 程式人生 > >分組揹包【DP】

分組揹包【DP】

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