多重揹包的二進制優化 悼念512汶川大地震遇難同胞――珍惜現在,感恩生活

/*今天剛看了揹包九講的多重揹包優化,經典啊!
將n[i]件等值的物品用二進制轉化爲log(n)件物品,這個是個很大的優化,
具體的處理是對每一件物品的費用和價值也都乘上相應的二進制係數。*/
#include <stdio.h>
#include <cstring>
int p[101],c[101],h[101];
int dp[101];
int n;
int max(int a,int b)
{
    if(a>b) return a;
    else return b;
}
inline void zero(int val,int cost)
{
    for(int i=n; i>=cost; i--)
        dp[i]=max(dp[i],dp[i-cost]+val);
}
inline void complete(int val,int cost)
{
    for(int i=cost; i<=n; i++)
        dp[i]=max(dp[i],dp[i-cost]+val);
}
inline void multiply(int cost,int weight,int amount)
{
    if(cost*amount>=n)
    {
        complete(weight,cost);
        return ;
    }
    for(int i=1; i<amount; i*=2)
    {
        zero(weight*i,cost*i);
        amount-=i;
    }
    zero(amount*weight,amount*cost);
}
int main()
{
    int m,test;
    scanf("%d",&test);
    while(test--)
    {
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        for(int i=0; i<m; i++) scanf("%d%d%d",&p[i],&h[i],&c[i]);
        for(int i=0; i<m; i++)
            multiply(p[i],h[i],c[i]);
        printf("%d\n",dp[n]);
    }
    return 0;
}


//下面是直接轉爲01揹包,不加二進制優化,時間複雜度顯而易見的差距。
#include <stdio.h>
#include <cstring>
int max(int a,int b)
{
    if(a>b) return a;
    else return b;
}
int p[101],h[101],c[101];
int dp[101];
int main()
{
    int n,m,test;
    scanf("%d",&test);
    while(test--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<m; i++) scanf("%d%d%d",&p[i],&h[i],&c[i]);
        memset(dp,0,sizeof(dp));
        int mm=-1;
        for(int i=0; i<m; i++)
            for(int j=0; j<c[i]; j++)
                for(int k=n; k>=p[i]; k--)
                {
                    dp[k]=max(dp[k],dp[k-p[i]]+h[i]);
                    if(dp[k]>mm) mm=dp[k];
                }
        printf("%d\n",mm);
    }
    return 0;
}


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