动态规划法求解0/1背包问题

一、求解0/1背包问题
1、问题描述
有n个重量分别为{w1,w2,…,wn}的物品,它们的价值分别为{v1,v2,…,vn},给定一个容量为C的背包。
设计从这些物品中选取一部分物品放入该背包的方案,每个物品要么选中要么不选中,要求选中的物品的总重量不能超过背包的容量,求具有最大的价值的装载方案。
2、蛮力法求解
动态规划法求解0/1背包问题_第1张图片
动态规划法求解0/1背包问题_第2张图片
3、证明0/1背包问题满足最优性原理
动态规划法求解0/1背包问题_第3张图片
4、问题分析
(1)第1步 问题结构分析(划分子问题)
动态规划法求解0/1背包问题_第4张图片
动态规划法求解0/1背包问题_第5张图片
(2)第2步 确定动态规划函数
动态规划法求解0/1背包问题_第6张图片
动态规划法求解0/1背包问题_第7张图片
动态规划法求解0/1背包问题_第8张图片
动态规划法求解0/1背包问题_第9张图片
(3)第3步 设计表格,填表
动态规划法求解0/1背包问题_第10张图片
动态规划法求解0/1背包问题_第11张图片
比如:
动态规划法求解0/1背包问题_第12张图片
动态规划法求解0/1背包问题_第13张图片
动态规划法求解0/1背包问题_第14张图片
动态规划法求解0/1背包问题_第15张图片
动态规划法求解0/1背包问题_第16张图片
动态规划法求解0/1背包问题_第17张图片
动态规划法求解0/1背包问题_第18张图片
动态规划法求解0/1背包问题_第19张图片
动态规划法求解0/1背包问题_第20张图片
动态规划法求解0/1背包问题_第21张图片
动态规划法求解0/1背包问题_第22张图片
动态规划法求解0/1背包问题_第23张图片
动态规划法求解0/1背包问题_第24张图片
5、算法设计

//问题表示
int n=5,C=10;  //5种物品,限制重量不超过10
int w[MAXN]={022654}; //下标0不用
int v[MAXN]={063546}; //下标0不用
//求解结果表示
int dp[MAXN][MAXW];
int x[MAXN];
int maxv;    //存放最优解的总价值
void Knapsack()   //动态规划法求0/1背包问题
{  int i,r;
   for (i=0;i<=n;i++)  //置边界条件dp[i][0]=0
      dp[i][0]=0;
   for (r=0;r<=C;r++)  //置边界条件dp[0][r]=0
      dp[0][r]=0;
   for (i=1;i<=n;i++)
   {  for (r=1;r<=C;r++)
        if (r<w[i])
           dp[i][r]=dp[i-1][r];
        else
           dp[i][r]=max(dp[i-1][r],dp[i-1][r-w[i]]+v[i]);
   }
}
void Buildx()    //回推求最优解
{  int i=n,r=C;
   maxv=0;
   while (i>=0)   //判断每个物品
   {
      if (dp[i][r]!=dp[i-1][r]) 
      {  x[i]=1;   //选取物品i
         maxv+=v[i];   //累计总价值
         r=r-w[i];
      }
      else
        x[i]=0;   //不选取物品i
      i--;
   }
}

6、算法分析
Knapsack()算法中含有两重for循环,所以时间复杂度为O(n×C),空间复杂度为O(n×C)。
7、滚动数组求解0/1背包问题
动态规划法求解0/1背包问题_第25张图片
动态规划法求解0/1背包问题_第26张图片
动态规划法求解0/1背包问题_第27张图片
8、练习
用动态规划法求解0/1背包问题:n=5, C=17 ,物品重量和价值分别是:w={3,4,7,8,9}和 v={4,5,10,11,13},求最优值和最优解,写出填表求解过程。
动态规划法求解0/1背包问题_第28张图片
动态规划法求解0/1背包问题_第29张图片

你可能感兴趣的:(算法)