• 0-1背包问题


    0-1背包问题

    时限:1000ms 内存限制:10000K  总时限:3000ms

    描述
    需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。
     
    输入
    多个测例,每个测例的输入占三行。第一行两个整数:n(n<=10)和c,第二行n个整数分别是w1到wn,第三行n个整数分别是p1到pn。
    n 和 c 都等于零标志输入结束。
     
    输出
    每个测例的输出占一行,输出一个整数,即最佳装载的总价值。
     
    输入样例
    1 2
    1
    1
    2 3
    2 2
    3 4
    0 0
     
    输出样例
    1
    4
    对于0-1背包问题来说,贪婪的策略有常用的四种。每种贪婪策略都采用多步过程来完成背包的装入。在每一步过程中利用贪婪准则选择一个物品装入背包。
       一种贪婪准则为:从剩余的物品中,选出可以装入背包的价值最大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够容量),然后是下一个价值最大的物品,如此继续下去。这种策略不能保证得到最优解。
      第二种准则从剩下的物品中选择可装入背包的重量最小的物品,如此继续下去直到不能满足条件为止。在一般情况下不一定能得到最优解。
      第三种是价值密度(价值重量比Pi/Wi)贪婪算法,这种选择准则为:从剩余物品中选择可装入包的Pi/Wi值最大的物品。这种策略也不能保证得到最优解。
      第四种则为启发式贪婪算法。
    下面的代码采用贪心策略一:
    #include <iostream>
    using namespace std;
     
    typedef struct mine{
         int weight;             //物品的重量
         int price;              //物品的价值
    } mine;
     
    int main()
    {
        int num,container;
        mine data[25];
        cin>>num>>container;
        while(true)
        {
            if(num==0&&container==0)
            break;
            for(int i = 0;i < num; i++)
                cin>>data[i].weight;
            for(i = 0;i < num; i++)                                                 
                cin>>data[i].price;
    
            for(int m = 0;m < num-1; m++)                               //将物品按价值排序
                for(int n = 0;n < num-m-1; n++)
                    if(data[n].price<data[n+1].price)
                    {
                        mine temp;
                        temp.price = data[n].price;
                        temp.weight = data[n].weight;
                        data[n].price = data[n+1].price;
                        data[n].weight = data[n+1].weight;
                        data[n+1].price = temp.price;
                        data[n+1].weight = temp.weight;
                    }
            int sumweight = 0;
            int sumprice = 0;
            for(int k = 0;k < num; k++)
                if(data[k].weight<=(container-sumweight))
                 {
                     sumprice += data[k].price;
                     sumweight += data[k].weight;
                 }
            
            cout<<sumprice<<endl;
            
            cin>>num>>container;
        }
        return 0;
    }
    

     并不可以保证得到最优解,例如:

    输入:

    10 100

    4 5 6 6 7 7 8 9 11 45

    7 9 11 12 13 14 15 17 21 89

    输出为192

    采用动态规划算法:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int n,c,i,j;
        cin>>n>>c;
        while(n!=0||c!=0)
        {
            int *w =new int[n];
            int *p =new int[n];
            int **a = new int*[n+1];
            for(i=0;i<=n;i++)
               a[i]= new int[c+1];
            for(i=0;i<n;i++)
              cin>>w[i];
            for(j=0;j<n;j++)
              cin>>p[j];
            for(int k=0;k<c+1;k++)
              a[0][k] = 0;
            for(i=0;i<n;i++)
                for(j=0;j<=c;j++)
                {
                    if(w[i]>j)a[i+1][j] = a[i][j];
                    else if(a[i][j]<a[i][j-w[i]]+p[i]) a[i+1][j] = a[i][j-w[i]]+p[i];
                    else a[i+1][j] = a[i][j];
                }
            cout<<a[n][c]<<endl;
            cin>>n>>c;
        }
      return 0;
    }
    

     对于上述同样的输入可以得到193,原因在于可以用重量为4和5的物品代替重量为11的物品,从而获得最大的价值。

    态度决定高度,细节决定成败,
  • 相关阅读:
    使用submit异步提交,阻止表单默认提交
    EasyDarwin流媒体服务器实现关键帧推送功能
    EasyDarwin开源手机直播方案:EasyPusher手机直播推送,EasyDarwin流媒体服务器,EasyPlayer手机播放器
    EasyDarwin开源手机直播方案:EasyPusher手机直播推送,EasyDarwin流媒体服务器,EasyPlayer手机播放器
    EasyDarwin流媒体云平台架构
    EasyDarwin流媒体云平台架构
    EasyDarwin流媒体服务器高性能优化方向
    EasyDarwin流媒体服务器高性能优化方向
    我们将要建立的EasyDarwin开源社区
    我们将要建立的EasyDarwin开源社区
  • 原文地址:https://www.cnblogs.com/lxk2010012997/p/4390557.html
Copyright © 2020-2023  润新知