背包问题(仅仅包含大小)-lintcode(c++)

之前在做一个公司的面试题时候,遇到过背包问题。我当时想都没有想直接跳过了。
最近一直再刷动态规划的题目,终于是刷到了这个题目。
题目介绍:
lintcode92:背包问题
在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]。
例如:
如果有4个物品[2, 3, 5, 7]
如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。
如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。
函数需要返回最多能装满的空间大小。

这个题目想了很久,思路是有一点点,代码实现却困难重重。
我的思路是设计一个bool v[m][A.size()]的数组,其中m表示背包的大小,A.size(),表示物品的集合。如果在背包大小为m的情况下,A.at(i)这个物品放置则为true,否则就是假。
还设置一个num[m],表示背包大小为m时可以放置东西的个数。(没有考虑都题意)

在思考了差不多有一个小时之后,我选择搜索一下思路。动态规划题目做了差不多快10个,几乎没有一个题目有着清晰的思路。

正确的思路:
设置一个容器bool v[m+1];v[i]表示是否可以放置i重量的物品。
初始化条件 v[0] = true; //一定可以放置0重量的物品。
最优子结构 v[i] = v[i] || v[i - A.at(j)]; //其中j从0-A.size();
循环条件:最顶层的循环从0-A.size(),底层循环从m-A.at(i);从高到底。
最后的结果:从v[m]向前寻找。

总结:
  动态规划解决问题的步骤很好掌握,不过确定最优子结构这个过程十分的难。多多积累,总会遇到有思路的。

代码如下:

class Solution {
public:
    int backPack(int x, vector<int> &A) {
         bool v[x+1];
         
         //初始化数据
         v[0] = true;
        for(int i = 1; i < x+1 ; i++)
        {
            v[i] = false;    
        } 
        
        //循环
        for(int i = 0 ; i < A.size() ; i++)
        {
            for(int j = x ; j >= A.at(i);j--)
            {
                v[j] = v[j] || v[j-A.at(i)];
            }
        } 
        
        for(int i = x ; i > 0 ;i--)
        {
            if(v[i])
            {
                return i; 
            }    
        } 
        
        //return 0;
    }
};
原文地址:https://www.cnblogs.com/qiny1012/p/9679847.html