zoukankan      html  css  js  c++  java
  • leetcode-21-knapsack

    322. Coin Change

    Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of

    money cannot be made up by any combination of the coins, return -1.You may assume that you have an infinite

    number of each kind of coin.

    解题思路:

    比较典型的背包问题。这里f[i]存储金额为i时使用硬币的最小数目,c[i]是硬币的价值,w[i]都为1,表示使用一个这样的硬币。

    状态转移方程:f[i] = min(f[i], f[i-coins[j]+1),针对i >= coins[j]。

    注意:数组要初始化。。f[i]都设为amount+1(作为一个最大值)。f[0]=0。

    int coinChange(vector<int>& coins, int amount) {
            if (amount == 0)
                return 0;
            int f[amount + 1];
            int i, j;
            // initialization
            f[0] = 0;
            for (i = 0; i <= amount; i++) {
                // initialization
                if (i > 0)
                    f[i] = amount + 1;
                for (j = 0; j < coins.size(); j++) {
                    if (i >= coins[j]) {
                        if (f[i - coins[j]] + 1 < f[i]) {
                            f[i] = f[i - coins[j]] + 1;
                        }
                    }
                }
            }
            // if amount can not be reached, f[amount] = amount+1
            return f[amount] > amount ? -1:f[amount];
        }

    416. Partition Equal Subset Sum 

    Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

    解题思路:

    首先,如果所有数目的和是奇数,那么是false。然后我们看一下sum /= 2是否可以得到。状态转移方程:

    dp[j] = max(dp[j], dp[j-nums[i] + nums[i])。初始化dp[0] = 0, dp[i] = sum+1。

    如果说几个数相加可以得到sum,则另外几个相加也可以得到sum。因此只要看dp[sum]是否为sum即可。

    bool canPartition(vector<int>& nums) {
             int sum = 0;
            for (int i = 0; i < nums.size(); i++) {
                sum += nums[i];
            }
            if (sum % 2 != 0) return false; 
            sum /= 2;
            int dp[sum + 1] = {sum + 1};
            dp[0] = 0;
            for (int i = 0; i < nums.size(); i++) {
                for (int j = sum; j >= nums[i]; j--) {
                    if (dp[j - nums[i]] + nums[i] > dp[j])
                        dp[j] = dp[j - nums[i]] + nums[i];
                }
            }
            return dp[sum] == sum;
        }

  • 相关阅读:
    51nod 1122 机器人走方格 V4(矩阵乘法)
    51nod 1092 回文字符串
    51nod 1254 最大子段和 V2(递推)
    容斥原理求gcd为k的数对个数
    51nod 1115 最大M子段和 V3
    51nod 1053 最大M子段和 V2(贪心)
    洛谷P1792 [国家集训队]种树
    洛谷P1484 种树(反悔贪心,双向链表+堆)
    51 nod 1052 最大M子段和
    51 nod 1051 最大子矩阵和
  • 原文地址:https://www.cnblogs.com/pxy7896/p/6709602.html
Copyright © 2011-2022 走看看