浅谈背包

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完全背包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;
}
复制代码

 

posted on   vCoders  阅读(171)  评论(0编辑  收藏  举报

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示