完全背包问题动态规划c++

来源:互联网 发布:无线多重网络什么意思 编辑:程序博客网 时间:2024/05/16 09:30
完全背包问题
【问题描述】
  设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选),使其重量的和小于等于M,而价值的和为最大。
【输入格式】
第一行:两个整数,M(背包容量,M<=200)N(物品数量,N<=30)
2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
【输出格式】
     仅一行,一个数,表示最大总价值。
【样例输入】knapsack.in
     10 4
     2 1
     3 3
     4 5
     7 9
【样例输出】knapsack.out
  max=12
 
 接下来要解决的是完全背包问题,比起01背包,完全背包问题不同的是它所有背包的数量都是无限大的。所以对于物品i,我们要做的不仅仅是选择加上i或者不加上i,而变成了加上1,2,3……个i小妖精【x
同样,用f[i][v]表示前i个物品,在总重不超过v时的最大值。我们假设一个k为i物品的数量,那么c[i]每次加上的应该是k-1时的最优解。即
f[i][v]=max(f[i-1][v],f[i][v-w[i]]+c[i])
需要注意的是,在完全背包中,我们是从小到大依次增加物品i的数量,那么相应的v的值也不断变大,所以v循环应从1——m(额这一点其实我也不太明白O(∩_∩)O||||哈哈~)
 
附上程序
<span style="font-size:24px;color:#666666;">#include<iostream>#include<cstdio>using namespace std;int m,n,w[31],c[31],f[31][201];int main(){scanf("%d%d",&m,&n);for(int i=1;i<=n;++i)scanf("%d%d",&w[i],&c[i]);for(int i=1;i<=n;++i)for(int v=m;v>=0;--v){if(v-w[i]>=0)f[i][v]=max(f[i-1][v],f[i][v-w[i]]+c[i]);else f[i][v]=f[i-1][v];}cout<<"max="<<f[n][m];return 0;}</span>

0 0
原创粉丝点击