动态规划解决背包问题

背包问题

问题摘要:

n个物品,m大小的背包

S[i]:每个物品的大小

V[i]:每个物品的价值

求: 背包装入的最大价值

 

动态规划:

1.定义: dp(i,j):装入前i个物品放入大小为j的背包所获得的最大价值

2.递推公式:

(1)装不下,即装入i-1个的最大值:

                                   dp(i,j) = dp(i-1,j)

(2)能装下,比较装入i-1个的最大值和装入i个的最大值(看第i个是否能发挥更大的价值): 

                                    dp()i,j) = max( dp(i-1,j) , dp(i-1,j-s[i])+ v[i])                                                                                                                    

3.初始化: dp(i,0) = dp(0,j) = 0

4.返回值 dp(n,m)

 

计算流程:

假设n = 3  s=2,3,1 v=1,2,5 m=5 

  i=1      dp(1,0)=0 (1,1)=0 (1,2)=1 (1,3)=1 (1,4)=1 (1,5)=1   

  i=2      dp(2,0)=0 (2,1)=2 (2,2)=2 (2,3)=3 (2,4)=3 (2,5)=3

  i=3      dp(3,0)=0 (3,1)=2 (3,2)=2 (3,3)=3 (3,4)=3 (3,5)=5

 

C++源代码:

class Solution{

public:

    int BackPack(int m,vector<int> s,vector<int> v)

    {

          if(s.empty() || v.empty())  return 0;

          

          int i = s.size() + 1;  //前i个

          int j = m + 1;  //大小

          vector<vector<int>> ret_back(i,vector<int>(j,0));

          

          for(int i=1;i<n;++i)

          {

              for(int j=1;j!=m;++j)

              {

                //装不下,i-1是因为索引从0开始 

                if(s[i-1] > j)

                  ret_back[i][j] = ret_back[i-1][j];

                //能装下

                else

                  ret_back[i][j] = max( ret_back[i-1][j] , ret_back[i-1][j-s[i]]+v[i]);

              }

          }

     return ret_back[i][j];

    }

};



//优化: dp数组每次只用i-1行的值,可以优化为一维数组

  

posted @ 2020-02-13 14:53  Duikerdd  阅读(244)  评论(0编辑  收藏  举报