码迷,mamicode.com
首页 > 其他好文 > 详细

0-1背包问题

时间:2016-11-06 02:35:07      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:blog   ack   for   最大   pac   容量   min   style   font   

问题:

  给定n种物品和一背包。物品 i 的重量是 wi ,其价值是 vi ,背包的容量为 c 。

  对于一件物品,只有装或者不装,因此该问题称为 0-1背包问题。

  问如何选择装入背包中的物品,使得装入背包中的物品总价值最大。

分析:

  n种物品 : 1 2 3 …… i …… n

  用 m( i , j ) 来表示可选物品为 i , i+1 , …… , n 而背包容量只剩下 j 时最优选择后背包中物品的价值。

  这时, m( i , j ) 递归定义如下:

  技术分享

  就是说对于整个问题,如果容量够装的下 i ,看下第 i 个物品装之后背包的价值大,还是不装背包价值大(i 装还是不装影响到其他物品)。 

  

算法思路:

  我们先计算第 n 个物品的,再计算 n-1 的,直至最上面的。

代码: 

  

void Knapack(int v[], int w[], int c, int n, int **m)
{
    int jMax = min(w[n] - 1, c);  
    for (int j = 0; j <= jMax; j++)//如果背包容量小于 n 的大小
    {
        m[n][j] = 0;    //则装不下 n
    }

    for (int j = w[n]; j <= c; j++)//如果背包容量大于 n 的大小
    {
        m[n][j] = v[n];        //则装得下 n
    }

    for (int i = n - 1; i>1; i--)
    {
        jMax = min(w[i] - 1, c);
        for (int j = 0; j <= jMax; j++)//如果背包容量小于 i 的大小  
        {
            m[i][j] = m[i + 1][j];//则不能装 i ,只好继续装后面的  
        }

        for (int j = w[i]; j <= c; j++) //如果背包容量大于 i 的大小  
        {
            m[i][j] = max(m[i + 1][j], m[i + 1][j - w[i]] + v[i]);//则看下到底装 i 会比较好,还是不装比较好   
        }
    }
    //这边需要特殊考虑一下
    m[1][c] = m[2][c];
    if (c >= w[1])
    {
        m[1][c] = max(m[1][c], m[2][c - w[1]] + v[1]);
    }
}

void Traceback(int m[][10],int w[],int c,int n,int x[])  
{  
    for(int i=1; i<n; i++)  
    {  
        if(m[i][c] == m[i+1][c])  
        {  
            x[i]=0;  
        }  
        else  
        {  
            x[i]=1;  
            c-=w[i];  
        }  
    }  
    x[n]=(m[n][c])?1:0;  
}  

 

0-1背包问题

标签:blog   ack   for   最大   pac   容量   min   style   font   

原文地址:http://www.cnblogs.com/jacklovelol/p/6034268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!