zoukankan      html  css  js  c++  java
  • 回溯法解0-1背包问题(王晓东算法例题)

    给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应怎样选择装入背包的物品,使得装入背包中物品的总价值最大?

    整个解的空间相当于一个二叉树,左边是0,代表不取这个物品,右边是1,代表取这个物品,然后进行dfs,回溯的时候改动。

    注意,这里应该有两个剪枝,我这里仅仅写了一个。

    #include<iostream>
    #include<string>
    #include<cstring>
    using namespace std;
    int n,TotCap,bestval;//物品的个数。背包的容量,最大价值
    const int N=1000;
    int val[N],w[N],x[N],bestx[N];//物品的价值,物品的重量。x[i]暂存物品的选中情况,物品的选中情况
    void dfs(int i,int cv,int cw)
    {  //cw当前包内物品重量,cv当前包内物品价值
        if(i>n)//结束
        {
            if(cv>bestval)
            {
                bestval=cv;
                for(i=1;i<=n;i++) 
    			bestx[i]=x[i];
            }
        }
        else 
            for(int j=0;j<=1;j++)  
            {
                x[i]=j;//取或者不取 
                if(cw+x[i]*w[i]<=TotCap)  
                {
                    cw+=w[i]*x[i];
                    cv+=val[i]*x[i];
                    dfs(i+1,cv,cw);
                    cw-=w[i]*x[i];
                    cv-=val[i]*x[i];
                }
            }
    }
    
    int main()
    {
        int i;
        bestval=0; 
        cout<<"请输入背包最大容量:"<<endl;;
        cin>>TotCap;
        cout<<"请输入物品个数:"<<endl;
        cin>>n;
        cout<<"请依次输入物品的重量:"<<endl;
        for(i=1;i<=n;i++) 
        cin>>w[i];
        cout<<"请依次输入物品的价值:"<<endl;
        for(i=1;i<=n;i++) 
        cin>>val[i];
        dfs(1,0,0);
        cout<<"最大价值为:"<<endl;
        cout<<bestval<<endl;
        cout<<"被选中的物品的标号依次是:"<<endl;
        for(i=1;i<=n;i++)
    	if(bestx[i]==1) 
        cout<<i<<" ";
        cout<<endl;
        return 0;
    }


  • 相关阅读:
    Vue-cli3中导入Cesium并配置
    Intellij IDEA中安装插件的两种方式
    Docker01——Ubuntu上安装Docker
    Java反射02——动态代理
    Java反射01——基本概念
    Docker安全配置问题
    马踏棋盘里面的一些小问题
    马踏棋盘算法用Java语言实现
    Android 中AIDL的使用与理解
    数据库技术中的触发器(Trigger)——和ContentObserver功能类似
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5091597.html
Copyright © 2011-2022 走看看