【背包模板】

int V;//容量  
//01
void zeroone(int cost,int val){//费用,价值  
    int i;  
    for(i=V;i>=cost;i--){  
        if(dp[i]<dp[i-cost]+val){  
            dp[i] = dp[i-cost]+val;  
        }  
    }  
}  
//完全背包
void complete(int cost,int val){//费用,价值  
    int i;  
    for(i=cost;i<=V;i++){  
        if(dp[i]<dp[i-cost]+val){  
            dp[i] = dp[i-cost]+val;  
        }  
    }  
}  
//多重背包
void multi(int cost,int val,int cnt){//费用,价值,数量  
    if(cost*cnt>=V){  
        complete(cost,val);  
        return ;  
    }  
    int k = 1;  
    while(k<cnt){  
        zeroone(k*cost,k*val);  
        cnt -= k;  
        k *= 2;  
    }  
    zeroone(cnt*cost,cnt*val);  
}  
//混合三种背包:
for(i=0;i<m;i++){
    scanf("%d%d%d%d",&v,&weight,&value,&n);
    if(v>V || weight>W)
        continue;
    if(n==1)
        zeroone(v,weight,value);
    else if(n==0)
        complete(v,weight,value);
    else
        multiply(v,weight,value,n);
}

//二维费用的背包:
void zeroone(int v,int weight,int value){
    int i,j;
    for(i=V;i>=v;i--)
        for(j=W;j>=weight;j--)
            if(dp[i][j]<dp[i-v][j-weight]+value)
                dp[i][j]=dp[i-v][j-weight]+value;
}

void complete(int v,int weight,int value){
    int i,j;
    for(i=v;i<=V;i++)
        for(j=weight;j<=W;j++)
            if(dp[i][j]<dp[i-v][j-weight]+value)
                dp[i][j]=dp[i-v][j-weight]+value;
}

void multiply(int v,int weight,int value,int count){
    if(v*count>=V || weight*count>=W){
        complete(v,weight,value);
        return;
    }
    int k=1;
    while(k<count){
        zeroone(k*v,k*weight,k*value);
        count-=k;
        k*=2;
    }
    zeroone(count*v,count*weight,count*value);
}

//分组背包:
for(i=1;i<=n;i++){  //枚举组
    for(j=m;j>=1;j--){ //背包容量
        for(k=1;k<=m;k++){ //不同费用的物品
            if(j>=k)         //转移方程有j-k,要保证j-k>=0
                dp[j] = max(dp[j],dp[j-k]+a[i][k]);
        }
    }
}



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值