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;
}

 

posted @ 2022-04-29 23:24  fourmii  阅读(28)  评论(0编辑  收藏  举报