(不想說第幾天了==)混合揹包

混合揹包問題
將01揹包,完全揹包,多重揹包混合起來,也就是有的物品可以取一次,或者可以取無限次,或者取得次數有一個上限。

for(int i=1;i<=n;i++)
{
    if(第i件物品屬於01揹包)
       ZeroOnePack(c[i],w[i]);
    else if(第i件物品屬於完全揹包)
       CompletePack(c[i],w[i]);
    else if(第i件物品屬於多重揹包)
       MultiplePack(c[i],w[i],n[i]);

有一個例題,是01揹包的混合,感覺蠻有意思的~

AreYouBusy HDU - 3535

題意:有n個集合,每個集合有m件物品,每個物品有一個s值,如果s=0,表示這些物品最少取1個,s=1表示這些物品最多取1個,s=2,表示這些物品任意取.

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;
#define inf 0x3f3f3f3f
const int maxn = 105;
int dp[maxn][maxn],c[maxn],v[maxn];
int main()
{
    int n,T,m,s;
    while(scanf("%d %d",&n,&T)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&m,&s);
            for(int i=1;i<=m;i++)
                scanf("%d %d",&c[i],&v[i]);
            if(s==0)
            {
                for(int j=0;j<=100;j++) dp[i][j]=-inf;
                for(int b=1;b<=m;b++)
                for(int j=T;j>=c[b];j--)
                    dp[i][j]=max(dp[i][j],v[b]+max(dp[i-1][j-c[b]],dp[i][j-c[b]]));
            }
            else if(s==1)
            {
                for(int j=0;j<=100;j++) dp[i][j]=dp[i-1][j];
                for(int b=1;b<=m;b++)
                for(int j=T;j>=c[b];j--)
                    dp[i][j]=max(dp[i][j],v[b]+dp[i-1][j-c[b]]);
            }
            else {
                for(int j=0;j<=100;j++) dp[i][j]=dp[i-1][j];
                for(int b=1;b<=m;b++)
                for(int j=T;j>=c[b];j--)
                {
                    dp[i][j]=max(dp[i][j],v[b]+dp[i][j-c[b]]);
                }
            }
        }
        if(dp[n][T]<0) dp[n][T]=-1;
        printf("%d\n",dp[n][T]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章