• leetcode(c++)(背包问题)


    #include <iostream>
    #include <vector>
    #include <numeric>
    
    using namespace std;
    
    bool canPartition(const vector<int>& nums)
    {
        int sum = accumulate(nums.begin(),nums.end(),0);
        if(sum % 2 != 0)return false;
        sum /= 2; 
        int n = nums.size();
        vector<vector<bool>>dp(n + 1,vector<bool>(sum + 1));
        for(int i = 0; i <= n; ++i)dp[i][0] = true;
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 1; j <= sum; ++j)
            {
                dp[i][j] = dp[i-1][j];
                if(j - nums[i-1] >= 0) dp[i][j] = dp[i][j] | dp[i-1][j - nums[i-1]];
            }
        }
        return dp[n][sum];
    
    }
    
    int findMaxFrom(const vector<string>& strs,int m, int n)
    {
        vector<vector<int>>dp(m+1,vector<int>(n+1));
        for(auto str:strs)
        {
            int one = 0, zero = 0;
            for(int i = 0; i < str.size(); ++i)
            {
                if(str[i] == '0')++zero;
                else ++one;
            }
            for(int i = m; i >= zero; --i)
            {
                for(int j = n; j >= one; --j)
                {
                    dp[i][j] = max(dp[i][j],dp[i-zero][j-one] + 1);
                }
            }
        }
        return dp[m][n];
    }
    
    int subSet(const vector<int>& nums, int S)
    {
        int n = nums.size();
        vector<vector<int>>dp(n+1,vector<int>(S+1));
        dp[0][0] = 1;
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 0; j <= S; ++j)
            {
                dp[i][j] = dp[i - 1][j];
                if(j - nums[i-1] >= 0)dp[i][j]+=dp[i-1][j-nums[i-1]];
            }
        }
        return dp[n][S];
    }
    
    int findTargetSumWays(const vector<int>& nums, int S)
    {
        int sum = accumulate(nums.begin(),nums.end(),0);
        if(S > sum || (S + sum) % 2 == 1) return 0;
        return subSet(nums,(sum + S) / 2);
    }
    
    int lastStoneWeightII(const vector<int>& nums)
    {
        int sum = accumulate(nums.begin(),nums.end(),0);
        int target = sum / 2;
        int n = nums.size();
        vector<vector<int>>dp(n + 1, vector<int>(target + 1));
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 1; j <= target; ++j)
            {
                dp[i][j] = dp[i-1][j];
                if(j - nums[i-1] >= 0)
                {
                    dp[i][j] = max(nums[i-1] + dp[i-1][j-nums[i-1]],dp[i-1][j]);
                }
            }
        }
        return sum - 2*dp[n][target];
    }
    
    int change(const vector<int>& nums,int amount)
    {
        int n = nums.size();
        vector<vector<int>>dp(n + 1, vector<int>(amount + 1));
        for(int i = 0; i <= n; ++i)
        {
            dp[i][0] = 1;
        }
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 1; j <= amount; ++j)
            {
                dp[i][j] = dp[i-1][j];
                if(j - nums[i-1] >= 0)
                {
                    dp[i][j] += dp[i][j-nums[i-1]];
                }
            }
        }
        return dp[n][amount];
    }
    
    int coinChange(const vector<int>& coins, int amount)
    {
        int n = coins.size();
        vector<vector<int>>dp(n + 1, vector<int>(amount + 1,INT_MAX));
        for(int i = 0; i <= n; ++i)
        {
            dp[i][0] = 0;
        }
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 0; j <= amount; ++j)
            {
                dp[i][j] = dp[i-1][j];
                if(j >= coins[i-1] && dp[i][j-coins[i-1]]!= INT_MAX)
                {
                    dp[i][j] = min(dp[i][j],dp[i][j-coins[i-1]]+1);
                }
            }
        }
        return dp[n][amount] == INT_MAX ? -1:dp[n][amount];
    }
    
    int change1(const vector<int>& nums, int amount)
    {
        int n = nums.size();
        vector<vector<int>>dp(n + 1,vector<int>(amount+1));
        for(int i = 0; i <= n; ++i)
        {
            dp[i][0] = 1;
        }
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 1;j <= amount ; ++j)
            {
                dp[i][j] = dp[i-1][j];
                if(j - nums[i-1] >= 0)dp[i][j]+=dp[i][j-nums[i-1]];
            }
        }
        return dp[n][amount];
    }
    
    int canPartition(int n, const vector<int>&prices,const vector<int>&weight,const vector<int>& amount)
    {
        int n0 = prices.size();
        vector<vector<int>>dp(n0+1,vector<int>(n+1));
        for(int i = 1; i <= n0; ++i)
        {
            for(int j = 1; j <= n; ++j)
            {
                dp[i][j] = dp[i-1][j];
                for(int k = 0; k <= amount[i-1]; ++k)
                {
                    if(j - k * prices[i-1] >= 0)
                    {
                        dp[i][j] = max(dp[i][j],dp[i-1][j-k*prices[i-1]] + k * weight[i-1]);
                    }
                }
            }
        }
        return dp[n0][n];
    }
    
    int main()
    {
        //LeetCode416
        vector<int>v{1,5,11,5};
        cout << canPartition(v) << endl;
        //LeetCode474
        
        vector<string>strs{"10","0001","111001","1","0"};
        int m = 5, n = 3;
        cout << findMaxFrom(strs,m,n) << endl;
    
        //LeetCode494
        vector<int>nums{1,1,1,1,1};
        int s = 3;
        cout << findTargetSumWays(nums,s) << endl;
    
        //LeetCode1049
        vector<int>numss{2,7,4,1,8,1};
        cout << lastStoneWeightII(numss) << endl;
    
        //完全背包问题
    
    
        //LeetCode322
        vector<int>coins{1,2,5};
        int amount =11;
        cout << coinChange(coins,amount) << endl;
    
        //LeetCode518
        vector<int>coin{1,2,5};
        amount = 5;
        cout << change1(coin,amount) << endl;
    
        //LintCode798
        vector<int>prices{3,2};
        vector<int>weights{300,160};
        vector<int>amounts{1,6};
        n = 8;
        cout << canPartition(n,prices,weights,amounts) << endl;
        return 0;
    }
  • 相关阅读:
    Codeforces 716C[数论][构造]
    HDU 5808[数位dp]
    Codeforces 611d [DP][字符串]
    Codeforces 404D [DP]
    HDU 5834 [树形dp]
    HDU 5521 [图论][最短路][建图灵感]
    矩阵
    kruskal 处理最短路 问题 A: 还是畅通工程
    Dijastra最短路 + 堆优化 模板
    CodeForces
  • 原文地址:https://www.cnblogs.com/fourmi/p/16209092.html
Copyright © 2020-2023  润新知