浅谈背包

1.01背包

for(int i=0; i<n; i++)

{

  for(int j=W; j>=w[i]; j--)  //从后向前更新

  {  

     if(dp[j]<dp[j-w[i]]+v[i])

        dp[j]=dp[j-w[i]]+v[i];

  }

}

若将背包装满 则初始化 dp[0] =0, dp[i] =-∞ i :1~W;

2.02完全背包

for(int i=0; i<n; i++)

{

  for(int j=w[i]; j>=W; j++)  //从前向后更新

  {  

     if(dp[j]<dp[j-w[i]]+v[i])

        dp[j]=dp[j-w[i]]+v[i];

  }

}

若将背包装满 则初始化 dp[0] =0, dp[i] =-∞ i :1~W;

 3.多重背包

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int SIZE=1000+16;
int dp[SIZE];
int main()
{
    int n;    //物品个数 
    int W;  //背包容量 
    int w[SIZE]; //每件物品的体积 
    int v[SIZE]; //每件物品的价值 
    int c[SIZE]; //每件物品的数目 
    int cnt=0; // 存储分解后物品的总数
    int val[SIZE]; //存储分解后每件物品的价值
    int size[SIZE]; //存储分解后每件物品的体积 
    cin>>n>>W;
    for(int i=0;i<n;i++)
    {
        cin>>w[i]>>v[i]>>c[i];
        
        for(int j=1;j<=c[i];j<<=1) // <<=1 相当于乘以2 
        {
             val[cnt]=j*v[i];
             size[cnt++]=j*w[i];
             c[i]-=j;    
        }
        
        if(c[i]>0)
        {
            val[cnt]=c[i]*v[i];
            size[cnt++]=c[i]*w[i];
        }
        
    }
    
    memset(dp,0,sizeof(dp));
    for(int i=0;i<cnt;i++)  //利用01背包求解
        for(int j=W;j>=size[i];j--)
        {
            if(dp[j]<dp[j-size[i]]+val[i])
                dp[j]=dp[j-size[i]]+val[i];
        }
    
    cout<<dp[W];
    
    return 0;
}
原文地址:https://www.cnblogs.com/program-ccc/p/4699916.html