D39|leetcode 70、322、279

70. 爬楼梯

思路:

这道题可以用完全背包的思路解答。步数为1和步数为2可以使用无数次,走n步可以看成背包的容量为n,题目可以转化成求解装满背包容量为n有多少种方法,注意这里的先走1步再走两步与先走两步再走一步是两种方法。dp[i]:背包容量为i有dp[i]种装法;递推关系:容量为i的背包可以由i-1的背包和i-2的背包装成的,所以dp[i]=dp[i-1]+dp[i-2];初始化:dp[0]=1;遍历顺序:这里求得是排列,所以先遍历背包后遍历物品。

代码:

class Solution {

public:

    int climbStairs(int n) {

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

        int m=2;

        dp[0]=1;

        for(int j=0;j<=n;j++)

        {

            for(int i=1;i<=m;i++)

            {

                if(j>=i)dp[j]+=dp[j-i];

            }

        }

        return dp[n];

    }

};


322. 零钱兑换

思路:

因为钱币可以使用无数次,所以本题是完全背包类的问题。dp[i]:装满容量为i的背包需要的最少硬币个数为dp[i];递推关系:dp[i]=min(dp[i-coins[i]]+1,dp[i]);初始值:dp[0]=0,因为递推关系里面取了min,所以其他的数值应该初始化为INT_MAX;遍历顺序:本题的问题是求解最少的硬币个数,不是求解实现最少硬币个数有多少种方法,所以本题按照排列或者组合方法求解都是可以的。

代码:

class Solution {

public:

    int coinChange(vector<int>& coins, int amount) {

        vector<int> dp(amount+1,INT_MAX);

        dp[0]=0;

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

        {

            for(int j=coins[i];j<=amount;j++)

            {

                if (dp[j - coins[i]] != INT_MAX)

                {

                    dp[j]=min(dp[j-coins[i]]+1,dp[j]);

                }   

            }

        }

        if(dp[amount]==INT_MAX) return -1;

        else return dp[amount];

    }

};


279. 完全平方数

思路:

本题也可看成是一个完全背包问题,相同的完全平方和数可以取到多次。dp[i]:组成和为i的最少完全平方数的数量;递推关系:dp[j]=min(dp[j-i*i]+1,dp[j]);初始值:dp[0]=0,其他值为INT_MAX;遍历顺序:先背包后物品或者先物品后背包均可。 这道题的整体思路和上面一道题是一致的。

代码:

class Solution {

public:

    int numSquares(int n) {

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

        dp[0]=0;

        for(int i=0;i*i<=n;i++)

        {

            for(int j=i*i;j<=n;j++)

            {

                if(dp[j-i*i]!=INT_MAX)

                {

                    dp[j]=min(dp[j-i*i]+1,dp[j]);

                }

            }

        }

        return dp[n];

    }

};

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

推荐阅读更多精彩内容