动态规划0-1背包问题

来源:互联网 发布:郑州编程班 编辑:程序博客网 时间:2024/06/08 11:14

最优子结构性质:动态规划算法的第一步是要刻画最优解的结构,即当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法求解的显著特征。

主要参考

我修改了里边的代码:物品编号从0开始;矩阵中的元素(i,j)表示容量为j,物品为0到i时的最大价值;用c++11重写。

结果

vector<vector<int>> package0_1(const vector<int> &w, const vector<int> &v, const int c)//n代表物品的个数{    int n = w.size(); // 物品数量    vector<vector<int>> mapping(n, vector<int>(c+1));    for(int j=w[0]; j<=c; ++j)        mapping[0][j] = v[0];    for(int i=1; i<n; ++i)    {        for(int j=0; j<w[i]; ++j)            mapping[i][j] = mapping[i-1][j];        for(int j=w[i]; j<=c; ++j)            mapping[i][j] = max(mapping[i-1][j], mapping[i-1][j-w[i]]+v[i]);    }    return mapping;}vector<int> answer(const vector<vector<int>> &m, const vector<int> &w, const int c){    vector<int> result;    int j=c;    for(int i=m.size()-1; i>0; --i)    {        if(m[i][j] != m[i-1][j])        {            result.push_back(i);            j -= w[i];        }    }    if(m[0][j]) result.push_back(0);    reverse(result.begin(), result.end());    return result;}int main(){    // 输入    vector<int> w {2,20,6,5,4}, v {6,3,5,4,6}; // 重量和价值列表    int c = 10; // 背包容量    // 得到mapping    vector<vector<int>> &&m = package0_1(w, v, c);    cout << "the mapping is:\n";    for(auto &i:m)    {        for(auto &j:i)            printf("%3d", j);        cout << endl;    }    // 得到物品编号    vector<int> &&result = answer(m, w, c);    cout << "the best answer is:\n";    for(auto i:result)        cout << i << " ";    return 0;}
0 0