背包问题与动态规划问题初学

01背包

状态转移方程:

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

本人初学,在网上找了N久的动态规划和01背包的资料,虽然有一些讲的很生动,我也在概念上理解了动态规划和01背包的原理,但是总觉得无法形象的表达整体的运算过程,于是画了个表格形象地记录一下这个过程

上面箭头表示了每次的比较的两个数据,较大的存放在箭头的尾部,根据观察可以看出,每次比较的都是本次第N个数据与上次循环结果的第(N-此次物品重量)个数据,也就是没放入这个物品之前的最优解。

每一列代表每个不同容量的背包的情况 每行代表放入不同物品的情况。

粘个一维数组实现的代码


1 #include <iostream>
2
3  using namespace std;
4
5  int main(void){
6 int cases=0;
7 int maxVolume=0;
8 int nGoods=0;
9 int weight[1024];
10 int value[1024];
11 int record[1024];
12 cin>>cases;
13 while(cases--){
14
15 memset(record,0,sizeof(record));
16
17 cin>>nGoods>>maxVolume;
18 for(int i=0;i<nGoods;i++)
19 cin>>value[i]>>weight[i];
20
21 for(i=0;i<nGoods;i++)
22 for(int j=maxVolume;j>=weight[i];j--)
23 if(record[j]<record[j-weight[i]]+value[i])
24 record[j]=record[j-weight[i]]+value[i];
25
26 cout<<record[maxVolume]<<endl;
27 }
28
29 return 0;
30 }
1 #include <iostream>
2
3  using namespace std;
4
5  int main(void){
6 int cases=0;
7 int maxVolume=0;
8 int nGoods=0;
9 int weight[1024];
10 int value[1024];
11 int record[1024];
12 cin>>cases;
13 while(cases--){
14
15 memset(record,0,sizeof(record));
16
17 cin>>nGoods>>maxVolume;
18 for(int i=0;i<nGoods;i++)
19 cin>>value[i]>>weight[i];
20
21 for(i=0;i<nGoods;i++)
22 for(int j=maxVolume;j>=weight[i];j--)
23 if(record[j]<record[j-weight[i]]+value[i])
24 record[j]=record[j-weight[i]]+value[i];
25
26 cout<<record[maxVolume]<<endl;
27 }
28
29 return 0;
30 }

多重背包

状态转移方程:

f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k<=n[i]}

(0<=k<=v/w[i])

待续...


原文地址:https://www.cnblogs.com/lfzark/p/1994397.html