赞
踩
我们从题切入,先看题目要求:
解题思路:
1:我们用到了二维数组,将f[i][j]表示为:将前i个物品放到了总体积为j的包里的情况下,包的最大总价值。
2:那么我们f[i][j]的表示方法如下:
针对第i个物品,我们有两种情况:
一:不放第i个物体:f[i][j]=f[i-1][j];
二:放第i个物体:f[i][j]=f[i-1][j-v[i]]+w[i];
所以f[i][j]=max{情况一,情况二},即f[i][j]=max{ f[i-1][j], f[i-1][j-v[i]]+w[i] }
基本思路就是如此,下面我们举个例子来帮助大家更好理解:
现在有三个物体,体积价值如下表:
那么我们可以根据f[i][j]这个二位数组得到一个表格:
表格的第一行,我们可以很轻松的写出来
根据第一行得出的数据和上面我们说的公式f[i][j]=max{ f[i-1][j], f[i-1][j-v[i]]+w[i] },我们可以退推出来剩下所有的表格内容:
示例:上图中绿色表格中内容应该为多少呢?
首先,该表格为f[2][3],那么f[2-1][3]我们根据第一行可知为6,f[1][3-2]+w[2]为16,取两个之间的最大值,所以图中绿色表格数值应为16。
如此下去,整个表格的所有内容都可以得出,即二维数组f[i][j]所有值都可以得出来,所以f[N][V]就可以得出来。
代码如下:
- #include<iostream>
- #include<cstring>
- #include<algorithm>
-
- using namespace std;
- const int N=1010;
- int n,m;//n个物品,背包容量为m
- int f[N][N];
- int v[N],w[N];//物体的体积和价值
- int main(){
- cin>>n>>m;
- //输入物体体积和价值
- for(int i=1;i<=n;i++)//数列下标从1开始,而不是0
- {
- cin>>v[i]>>w[i];
- }
-
- //初始化第一行,这段代码删去其实也可以,只需要将下面初始其他行的代码i的初始值从2改成1即可
- for(int i=0;i<=m;i++)
- {
- //f[1][i]=v[1]<=i?w[1]:0;
- f[1][i]=v[1]<=i?w[1]:0;
- }
-
- //初始化其他行
- for(int i=2;i<=n;i++)
- {
- for(int j=0;j<=m;j++)
- {
- f[i][j]=f[i-1][j];
- //第i个物体重量小于包总容量再考虑将第i个放入包内
- if(v[i]<=j)
- {
- f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
- }
- }
- }
- //输出最终结果
- cout<<f[n][m]<<endl;
- return 0;
-
-
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。