D37|leetcode 1049、494、474

1049. 最后一块石头的重量 II

思路:

这道题的思路和第416题是一致的,可以把石头分成重量相近的两堆然后相撞,这样的剩余重量是最小的。由此可将问题转换成一个容量为sum/2的背包能装的最大价值问题。dp[i]:容量为i的背包能装的最大价值为dp[i];初始化:dp[0]=0;递推关系:dp[i]=max(dp[i],dp[i-weight[i]]+weight[i]);遍历顺序:先遍历物品,后遍历背包,背包逆序遍历。

代码:

class Solution {

public:

    int lastStoneWeightII(vector<int>& stones) {

        vector<int> dp(1501,0);

        int sum=0;

        for(int i=0;i<stones.size();i++)

        {

            sum+=stones[i];

        }

        int target=sum/2;

        for(int i=0;i<stones.size();i++)

        {

            for(int j=target;j>=stones[i];j--)

            {

                dp[j]=max(dp[j],dp[j-stones[i]]+stones[i]);

            }

        }

        return (sum-dp[target])-dp[target];

    }

};


494. 目标和

思路:

这道题可以转化为两个正数right、left,两个数做差为target,两个数的和为sum,求解容量为left的背包有多少种装法。dp[i]:容量为i的背包有dp[i]种装法,初始化:dp[0]=1,递推关系:dp[i]可以分解成1+dp[i-1]、2+dp[i-2]......,遍历顺序:先物品后背包,背包倒序遍历。

代码:

class Solution {

public:

    int findTargetSumWays(vector<int>& nums, int target) {

        int sum=0;

        for(int i=0;i<nums.size();i++)

        {

            sum+=nums[i];

        }

        if (abs(target) > sum) return 0;

        if ((target + sum) % 2 == 1) return 0;

        int left=(sum+target)/2;

        vector<int> dp(10001,0);

        dp[0]=1;

        for(int i=0;i<nums.size();i++)

        {

            for(int j=left;j>=nums[i];j--)

            {

                dp[j]+=dp[j-nums[i]];

            }

        }

        return dp[left];

    }

};


474. 一和零

思路:

这道题目可以看成是一个二维的背包问题,每个字串可以看成物品,物品的重量是二维的,即每个字串中0的个数和1的个数。dp[i][j]:有i个0,j个1的背包能装的最多字串为dp[i][j]。初始化:dp[0][0]=0。递推关系:针对某一个物品,不装入背包时能装的最多字串是dp[i][j],如果装入背包时,能装的最多字串是dp[i-x][j-y]+1,x表示该物品中0的个数,y表示该物品中1的个数。将两者情况取最大值就能得到递推关系。遍历顺序:先遍历物品,后遍历背包,背包从后向前遍历。

代码:

class Solution {

public:

    int findMaxForm(vector<string>& strs, int m, int n) {

        vector<vector<int>> dp(m+1,vector<int>(n+1,0));

        for(string str:strs)

        {

            int x=0,y=0;

            for(char p:str)

            {

                if(p=='0')

                {

                    x++;

                }else

                {

                    y++;

                }

            }

            for(int i=m;i>=x;i--)

            {

                for(int j=n;j>=y;j--)

                {

                    dp[i][j]=max(dp[i][j],dp[i-x][j-y]+1);

                }

            }


        }

        return dp[m][n];

    }

};

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容