• 背包问题


    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;
    }
  • 相关阅读:
    hdu2037 今年暑假不AC[贪心][区间调度问题]
    Features Track[STL map]
    Characters with Hash[签到题]
    hdu2094产生冠军[STL set]
    2018ECNA Difference[时空复杂度]
    hdu1276士兵队列训练问题[简单STL list]
    20190815网络与信息安全领域专项赛线上赛misc WriteUp
    hdu1873 看病要排队[优先队列]
    Pygame 贪吃蛇
    Windows安装Python3 curses模块
  • 原文地址:https://www.cnblogs.com/inception6-lxc/p/9224416.html
Copyright © 2020-2023  润新知