完全背包问题

完全背包问题

实例:n=4,b=10
v1=1, v2=3, v3=5, v4=9
w1=2, w2=3, w3=4, w4=7
n是背包的种类,b是书包的总重量

//安利北京大学mooc 此算法是老师所讲算法的一个实现
//https://www.icourse163.org/learn/PKU-1002525003#/learn/content?type=detail&id=1003850904&cid=1004665219

#include<iostream>
#include<algorithm>
using namespace std;
const int N=4;
const int B=10;
const int v[4]={1,3,5,9};
const int w[4]={2,3,4,7};
int f[100][100];
//标记函数
int ii[100][100];
int main(){
  
    //建模
    //先进行数据的初始化
    for(int i=0;i<=B;i++){
        f[0][i]=0;
    }
    for(int i=0;i<=N;i++){
        f[i][0]=0;
    }
    for(int i=1;i<=B;i++){
        int a =(i/w[0]);
        cout<<a<<'\n';
        f[1][i]=a*v[0];
    }
    //
    //标记数组的操作,下同
    for(int i=1;i<=B;i++){
        if(i>=w[0]){
            ii[1][i]=1;
        }
    }
    /
    //开始正式的动态规划
    for(int k=2;k<=N;k++){
        for(int y=1;y<=B;y++){
            if(y-w[k-1]>=0){
                f[k][y]= max(f[k-1][y],f[k][y-w[k-1]]+v[k-1]);
                /
                if(f[k-1][y]>f[k][y-w[k-1]]+v[k-1]){
                    ii[k][y]=ii[k-1][y];
                }else{
                    ii[k][y]=k;
                }
                /
            }else{
                f[k][y]= f[k-1][y];
                ///
                ii[k][y]=ii[k-1][y];
                ///
            }

        }
    }
    //打印数组
    for(int i=1;i<=N;i++){
        for(int j=1;j<=B;j++){
            cout<<f[i][j]<<' ';
        }
        cout<<endl;
    }
    for(int i=1;i<=N;i++){
        for(int j=1;j<=B;j++){
            cout<<ii[i][j]<<' ';
        }
        cout<<endl;
    }

    //对数数组进行逆向求解
    int x[100];
    for(int i=1;i<=N;i++){
        x[i]=0;
    }
    int y=B,k=N;


   while(ii[k][y]!=k){
    k=k-1;
   }
    do{
        k=ii[k][y];
        x[k]=1;
        y=y-w[k-1];
        while(ii[k][y]==k){
            y=y-w[k-1];
            x[k]=x[k]+1;
        }
    }while(ii[k][y]!=0);



    for(int i=1;i<=N;i++){
        cout<<x[i]<<'\t';
    }




    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值