01背包、完全背包、多重背包

http://www.cnblogs.com/Kalix/p/7617856.html  01背包问题

https://www.cnblogs.com/Kalix/p/7622102.html   完全背包问题

https://blog.csdn.net/mystery_guest/article/details/51878140      多重背包二进制优化

01背包

二维版

for(int i=1;i<=n;i++)
{
    for(int j=1;j<=m;j++)
    {
        if(weight[i]<=j)
        dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);//能放下拿或者不拿
        else
        dp[i][j]=dp[i-1][j]; 
    }
}

一维版

for(int i=1;i<=n;i++)
{
    for(int j=m;j>=weight[i];j++)
    dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
}

完全背包

二维版

for(int i=1;i<=n;i++)
{
    for(int j=1;j<=m;j++)
    {
        if(weight[i]<=j)
        dp[i][j]=max(dp[i-1][j],dp[i][j-weight[i]]+value[i]);//能放下拿或者不拿
        else
        dp[i][j]=dp[i-1][j]; 
    }
}

一维版

for(int i=1;i<=n;i++)
{
    for(int j=weight[i];j<=m;j++)
    dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
}

多重背包+二进制优化

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 1000         //物品个数 
#define M 100000000    //所有物品可能的最大价值 
int m[N],c[N],w[N],f[M];
int V;
int max(int a,int b){return a>b?a:b;}
void ZeroOnePack(int cost,int weight)
{
    int v;
    for(v=V;v>=cost;v--) f[v]=max(f[v],f[v-cost]+weight);
}
void CompletePack(int cost,int weight)
{
    int v;
    for(v=cost;v<=V;v++)
        f[v]=max(f[v],f[v-cost]+weight);
}
void MultiplePack(int cost,int weight,int amount)
{
    int k;
    if(cost*amount>=V)
    {
        CompletePack(cost,weight);
        return;
    }
    k=1;
    while(k<amount)
    {
        ZeroOnePack(k*cost,k*weight);
        amount=amount-k;
        k=k*2;
    }
    ZeroOnePack(amount*cost,amount*weight);
}
int main()
{
    int n,i;
    scanf("%d %d",&n,&V);
    for(i=0;i<n;i++) scanf("%d %d %d",m+i,c+i,w+i);
    for(i=0;i<n;i++) MultiplePack(c[i],w[i],m[i]);
    printf("%d\n",f[V]);return 0;
}

猜你喜欢

转载自www.cnblogs.com/wpbing/p/9507815.html