算法分析与设计实验:01背包

时间:2020-04-21
本文章向大家介绍算法分析与设计实验:01背包,主要包括算法分析与设计实验:01背包使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

问题描述:

有N件物品和一个容量为V的背包。第i件物品的重量是weight[i],价值是value[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。注意,与背包问题不同的是,每件物品只有整个装入和不装入两个选项,且每件物品只能装入一次。

算法描述:

使用f(i,v)表示将前i个物品选择性装入剩余容量为v的背包时能得到的最大价值。这里我们把第i件物品和前i-1件物品分开来看,第i件物品只有装和不装两种选择。

1.如果不装的话剩余容量不减少,价值也不变,因此在这种情况下f(i,v)=f(i-1,v)

2.如果装的话则容量减少,价值增加,因此在这种情况下f(i,v)=f(i-1,v-weight[i])+value[i]

从自顶向下的视角看,如果装了第i个物品的话在下一层就要求解前i-1件物品在剩余容量减少的情况下的最大价值,如果没有装则要求解前i-1件物品在剩余容量不变的情况下的最大价值。

因此对于第i件物品的装和不装问题我们只要取两者的最大值就可以了。所以可以得到状态转移方程:

f(i,v)=f(i-1,v)                                           (v<weight[i],即剩余容量不足,不能放入物品)

f(i,v)=f(i-1,v-weight[i])+value[i]                (v>=weight[i],即剩余容量充足)

 

代码:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 //f[i][v]=max{ f[i-1][v],f[i-1][v-w[i]]+val[i] }
 6 //f[v]=max(f[v-weight[i]]+value[i],f[v])
 7 int solve(int n,int capacity,vector<int> &weight,vector<int> &value)
 8 {
 9     if(n<0||capacity<=0)
10         return 0;
11     vector<int> f(capacity+1);
12     for(int i=0;i<n;i++)
13     {
14         for(int v=capacity;v>0;v--)
15         {
16             if(v>=weight[i]) f[v]=max(f[v-weight[i]]+value[i],f[v]);
17         }
18     }
19     return f[capacity];
20 }
21 
22 int main()
23 {
24     int n,capacity;
25     cin>>n>>capacity;
26     vector<int> weight(n);
27     vector<int> value(n);
28     for(int i=0;i<n;i++)
29     {
30         cin>>weight[i]>>value[i];
31     }
32 
33     int ans=solve(n,capacity,weight,value);
34     cout<<ans<<endl;
35     return 0;
36 }

原文地址:https://www.cnblogs.com/misaka-cn-cs/p/12743480.html