01背包问题
2017-11-05 23:35
148 查看
问题描述
给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装M重量的背包.问怎么装使得所装价值最大.每个物品只有一个.
输入格式
输入的第一行包含两个整数n, m,分别表示物品的个数和背包能装重量。
以后N行每行两个数Wi和Vi,表示物品的重量和价值
输出格式
输出1行,包含一个整数,表示最大价值。
样例输入
3 5
2 3
3 5
4 7
样例输出
8
数据规模和约定
1<=N<=200,M<=5000.
方法1:
方法2:(用一维数组实现)
![](https://img-blog.csdn.net/20171108201944571?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvWmhhbnlleWU3NDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
其中代码的第24~31行可以简化,如下:
for(int i=0; i<n; i++)
{
for(int j=c; j>=weight[i]; j--) //j为背包容量,其中容量为0时,价值势必为0,所以更新dp[]时,不用循环dp[0]
{
dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
}
}
给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装M重量的背包.问怎么装使得所装价值最大.每个物品只有一个.
输入格式
输入的第一行包含两个整数n, m,分别表示物品的个数和背包能装重量。
以后N行每行两个数Wi和Vi,表示物品的重量和价值
输出格式
输出1行,包含一个整数,表示最大价值。
样例输入
3 5
2 3
3 5
4 7
样例输出
8
数据规模和约定
1<=N<=200,M<=5000.
方法1:
#include <iostream> #include <cstring> using namespace std; int main() { int n,c; cin>>n>>c; /*这里要注意数组申请空间是要多申请一个 0号位赋值为0,这是为了在递推过程中f[][1]或f[1][]的值可正常推出 */ int *weight=new int[n+1];//重量 int *value=new int[n+1]; //价值 int **f=new int*[n+1];// f[i][j]表示在背包容量为j的情况下, 前i件宝贝的最大价值 for(int i=0; i<=n; i++) { f[i]=new int[c+1]; } for(int i=0; i<=n; i++) f[i][0]=0; for(int i=0; i<=c; i++) f[0][i]=0; for(int i=1; i<=n; i++) { cin>>weight[i]>>value[i]; } /* | 0 i=0 or w=0 f[i,w]=| f[i-1,w] wi>w | max(vi+f[i-1,w-wi],f[i-1,w]) i>0 and w>=wi */ for(int i=1; i<=n; i++) { for(int j=1; j<=c; j++) { if(j<weight[i]) //背包装不下第i个物品,f[][]为前i-1件物品的最大价值 f[i][j]=f[i-1][j]; else //背包可以装下第i个物品,如果放比不放价值大,则放 f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]]+value[i]); } } cout<<f [c]<<endl; return 0; } //这种方法空间利用率不高!!!
方法2:(用一维数组实现)
#include <iostream> #include <cstring> using namespace std; int main() { int n;//物品个数 int c;//背包容量 cin>>n>>c; int *weight=new int ;//重量 int *value=new int ; //价值 for(int i=0; i<n; i++) { cin>>weight[i]>>value[i]; } //数组多申请一个元素,容量从0~C, int dp[c+1]; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) { for(int j=c;j>0;j--) //j为背包容量,其中容量为0时,价值势必为0,所以更新dp[]时,不用循环dp[0] { if(j>=weight[i]) dp[j]=max(dp[j],dp[j-weight[i]]+value[i]); } } cout<<dp[c]<<endl; return 0; }
其中代码的第24~31行可以简化,如下:
for(int i=0; i<n; i++)
{
for(int j=c; j>=weight[i]; j--) //j为背包容量,其中容量为0时,价值势必为0,所以更新dp[]时,不用循环dp[0]
{
dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);
}
}
相关文章推荐
- UVA - 10306 e-Coins 二维的01背包问题
- 背包问题(01背包和完全背包)
- 采药 水题 dp 01背包问题 luogu1048
- [01背包]NOIP2001 PJ T4 装箱问题
- 01背包问题
- C#解决01背包问题
- 深度优先搜索+动态规划——01背包类似问题
- 01背包问题(回溯算法实现)
- 苹果(01背包问题)——动态规划
- code[vs] 1014 装箱问题(01背包)
- Python基于回溯法解决01背包问题实例
- hdoj problem 1203 I NEED A OFFER!(动态规划&&背包问题(01背包问题))
- hihoCoder - 1038 - 01背包 (经典动态规划问题!!)
- DP-01背包问题
- HDU 2602 Bone Collector(01背包问题)
- 动态规划之01背包问题
- hdu 2602 01背包问题
- 一维数组解决01背包问题
- 01背包问题小结
- POJ-3211 Washing Clothes[01背包问题]