蓝桥杯 算法提高 01背包

来源:互联网 发布:淘宝专题文案范文 编辑:程序博客网 时间:2024/06/05 06:01

 算法提高 01背包  
时间限制:1.0s   内存限制:256.0MB 
问题描述
  给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装M重量的背包.问怎么装使得所装价值最大.每个物品只有一个.
输入格式
  输入的第一行包含两个整数n, m,分别表示物品的个数和背包能装重量。
  以后N行每行两个数Wi和Vi,表示物品的重量和价值
输出格式
  输出1行,包含一个整数,表示最大价值。
样例输入
3 5
2 3
3 5
4 7
样例输出
8
数据规模和约定
  1<=N<=200,M<=5000.

思路分析:
每件物品仅有一件,可选择放或不放
可用dp[i][j]表示前 i 件物品恰放入容量为 j 的背包可获得的最大价值,则有以下的动态规划函数:
(1)   dp[i][0] = dp[0][j] = 0 
(2)   dp[i][j] = dp[i-1][j] j<wi  
 dp[i][j] = max{dp[i-1][j], dp[i-1][j-w[i]]+v[i]}j>wi
在此说明 (2) 的两种情况: 
情况一: 第i个物品的重量大于背包的容量,则装人前i个物品得到的最大价值和装入前i-1个物品得到的最大价是相同的,即物品i不能装入背包
情况二: 如果第i个物品的重量小于背包的容量,则会有一下两种情况:
(a)如果第 i 件放进去,则应先求得在容量为 j-w[i] 的背包中放入前 i-1 件物品的最大价值,再加上第 i 件物品的价值,就可得到总价值
(b)如果第i个物品没有装入背包,则背包中物品价值就等于把前i-1个物品装入容量为j的背包中所取得的价值。
显然,取二者中价值最大的作为把前 i 个物品装入容量为 j 的背包中的最优解。


假设现有容量10kg的背包,另外有3个物品,物品1重量为3kg,价值为4;物品2重量为4kg,价值为5;物品3重量为5kg,价值为6。

根据dp[i][j] = max{dp[i-1][j], dp[i-1][j-w[i]]+v[i]},对物体个数及背包重量进行递推,列出一个表格(见下表),表格来自

(http://blog.csdn.net/fg2006/article/details/6766384?reload)



#include <iostream>#include <algorithm>using namespace std;int max(int a, int b) { return (a>b) ? a : b; }int binaryKnapsack(int numItems, int capacity, int *w, int *v);int main(int argc, char const *argv[]) {  int n, m;  cin >> n >> m;  int w[n], v[n];  for (int i = 0; i < n; i++) {    cin >> w[i] >> v[i];  }  int MaxWeight = binaryKnapsack(n, m, w, v);  cout << MaxWeight << endl;  return 0;}int binaryKnapsack(int numItems, int capacity, int *w, int *v){  int dp[numItems+1][capacity+1];  for (int i = 0; i <= numItems; i++) {    for (int j = 0; j <= capacity; j++) {      if(i == 0 || j == 0)        dp[i][j] = 0;      else if(w[i-1] <= j)//w、v数组的序号是从0开始的        dp[i][j] = max(dp[i-1][j-w[i-1]]+v[i-1], dp[i-1][j]);      else        dp[i][j] = dp[i-1][j];    }  }  return dp[numItems][capacity];}



0 0