• 背包问题


    1.01背包问题

    https://blog.csdn.net/xp731574722/article/details/70766804

    https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html

    /*01背包问题*/
    #include<iostream>
    #include<vector>
    #include<algorithm>
    
    using namespace std;
    
    //找不超过容量的最大价值
    void Findmax(vector<int>&v, vector<int>&c, int C, vector<vector<int>>&dp){                                                        
        for (int i = 1; i <v.size(); i++){
            for (int j = 1; j <=C; j++){
                if (c[i] > j){
                    dp[i][j] = dp[i - 1][j];//如果第i件物品所占容量大于当前背包容量,则不放入
                }
                else{
                    dp[i][j] = max(dp[i - 1][j],dp[i-1][j-c[i]]+v[i]);//选择不放入第i个,和放入第i个后价值最大的
                }
            }
        }
    
    }
    
    //找选择的物品的序号
    void Findpos(int i, int j, vector<int>&v, vector<int>&c, vector<int>&item, vector<vector<int>>&dp)
    {
        if (i > 0)
        {
            //cout << dp[i][j] << endl;
            //cout << dp[i - 1][j - c[i]] + v[i];
    
            if (dp[i][j] == dp[i - 1][j])//相等说明没装第i件商品
            {
                item[i] = 0;//全局变量,标记未被选中
                Findpos(i - 1, j,v,c,item,dp);
            }
            
            else if (j - c[i] >= 0 && dp[i][j] == dp[i - 1][j - c[i]] + v[i])
            {
                item[i] = 1;//标记已被选中
                //cout << i << endl;
                //cout << j << endl;
                Findpos(i - 1, j - c[i],v,c,item,dp);//回到装包之前的位置
            }
        }
    }
    
    
    int main(){
        vector<int>v = { 0, 60, 100, 120 };//每件物品对应价值
        vector<int>c = { 0, 1, 2, 3 };//每件物品所占容量,第一个零是为了方面从序号1开始所以补的
        int C = 5;
        vector<vector<int>>res(v.size(), vector<int>(C+1, 0));//res[i][j]代表前i件物品恰放入容量j(还能装j的容量)的背包的最大价值
        Findmax(v, c, C,res);
        //填表
        for (int i = 0; i < res.size(); i++){
            for (int j = 0; j < res[0].size(); j++){
                cout << res[i][j] << " ";
            }
            cout << endl;
        }
        cout << res[v.size()-1][C] << endl;//最大价值
        vector<int>item(v.size(), 0);
        Findpos(v.size() - 1, C, v, c, item, res);
        for (int i = 0; i < item.size(); i++){
            if (item[i] != 0){
                cout << i<< endl;
            }
        }
        system("pause");
        return 0;
    }

     2.完全背包问题

    https://blog.csdn.net/na_beginning/article/details/62884939

    /*完全背包问题*/
    #include<iostream>
    #include<vector>
    #include<algorithm>
    
    using namespace std;
    
    //找不超过容量的最大价值
    void Findmax(vector<int>&v, vector<int>&c, int C, vector<vector<int>>&dp){                                                        
        for (int i = 1; i <v.size(); i++){
            for (int j = 1; j <=C; j++){
                if (c[i] > j){
                    dp[i][j] = dp[i - 1][j];//如果第i件物品所占容量大于当前背包容量,则不放入
                }
                else{
                    dp[i][j] = max(dp[i - 1][j],dp[i][j-c[i]]+v[i]);//此处与01背包区别
                }
            }
        }
    
    }
    
    //找选择的物品的序号
    void Findpos(int i, int j, vector<int>&v, vector<int>&c, vector<int>&item, vector<vector<int>>&dp)
    {
        if (i > 0)
        {
            //cout << dp[i][j] << endl;
            //cout << dp[i - 1][j - c[i]] + v[i];
    
            if (dp[i][j] == dp[i - 1][j])//相等说明没装第i件商品
            {
                item[i] = 0;//全局变量,标记未被选中
                Findpos(i - 1, j,v,c,item,dp);
            }
            
            else if (j - c[i] >= 0 && dp[i][j] == dp[i - 1][j - c[i]] + v[i])
            {
                item[i] = 1;//标记已被选中
                //cout << i << endl;
                //cout << j << endl;
                Findpos(i - 1, j - c[i],v,c,item,dp);//回到装包之前的位置
            }
        }
    }
    
    
    int main(){
        vector<int>v = { 0, 1, 3, 5,9 };//每件物品对应价值
        vector<int>c = { 0, 2, 3, 4,7 };//每件物品所占容量,第一个零是为了方面从序号1开始所以补的
        int C = 10;
        vector<vector<int>>res(v.size(), vector<int>(C+1, 0));//res[i][j]代表前i件物品恰放入容量j(还能装j的容量)的背包的最大价值
        Findmax(v, c, C,res);
        //填表
        for (int i = 0; i < res.size(); i++){
            for (int j = 0; j < res[0].size(); j++){
                cout << res[i][j] << " ";
            }
            cout << endl;
        }
        cout << res[v.size()-1][C] << endl;//最大价值
        vector<int>item(v.size(), 0);
        Findpos(v.size() - 1, C, v, c, item, res);
        for (int i = 0; i < item.size(); i++){
            if (item[i] != 0){
                cout << i<< endl;
            }
        }
        system("pause");
        return 0;
    }
  • 相关阅读:
    hypermesh生成MNF柔性体
    手机拍照参数的调整
    周金涛生前20篇雄文精华,一文尽览
    什么是DA控制
    win7系统程序未响应怎么办
    如何在老惠普电脑上安装windows xp系统
    linux的学习在runoob.com网站
    K:红黑树
    K:图的存储结构
    Q:链表的倒数第K个元素
  • 原文地址:https://www.cnblogs.com/inception6-lxc/p/9224416.html
Copyright © 2020-2023  润新知