Week15

Week15

Dynamic Programming
question source: Integer Break

question description

Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

Example 1:

Input: 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.
Example 2:

Input: 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.

解决方法

题目是说判断一个数能最少用多少个平方数之和表示出来。这道题的标签是DP问题。本来想是否能用贪心算法表示出来,先将这个数分割成最大的平方数和另一个数,然后在另一个数中重复这个做法。但是很快就能看出一个反例。12 = 9 + 1 + 1 + 1需要4个,而最少其实是12 = 4 +4+4。然后就想用动态规划来解决了。
先定义子问题,num[i]定义为i这个数能最小多少个平方数之各和来表示。则问题的解为num[n]。

n u m [ i ] = m i n { n u m [ i j j ] + 1 , i > = j j } num[i] = min \{num[i - j * j] + 1, i >= j * j\}
然后定义开始值。要多一个额外的量num[0]为0, nums[1]为1。

class Solution {
public:
    int numSquares(int n) {
        int num[n + 1];
        num[0] = 0;
        num[1] = 1;
        for(int i = 2; i <= n; i++){
            int min = i;
            for(int j = 2; j * j <= i; j++){
                if(min > num[i - j * j] + 1){
                    min = num[i - j * j] + 1;
                }
            }
            num[i] = min;
        }
        return num[n];
    }
};

算法复杂度是 O ( n l o g n ) O(nlogn)

这题的另一个标签为Math,所以是可以通过数学方法来解决了。有一个定理叫四平方和定理,每一个正整数均可表示4个整数的平方和。还有一个Legendre’s three-square theorem,是说一个自然数能被表示为三个平方之和当且仅当它不符合 n = 4 a ( 8 b + 7 ) n = 4^a(8 * b + 7) ,a和b是整数。因此可以用这些数学定理来解决。首先判断这个数是否是某个数的平方,如果是,则返回1。其次,再判断能否分为2个数之和,如果是,则返回2,再判断是否是否符合前面的表达式,如果是,则返回4,否则返回3。

class Solution {
public:
    bool isSquare(int n){
        int sqr = floor(sqrt(n));
        return sqr * sqr == n;
    }
    int numSquares(int n) {
        if(isSquare(n)){
            return 1;
        }
        
        for(int i = 1; i * i < n; i++){
            if(isSquare(n - i * i)){
                return 2;
            }
        }
        
        int a = 1;
        while(n % (4 * a) == 0){
            a *= 4;
        }
        if((n / a) % 8 == 7){
            return 4;
        }
        
        return 3;
    }
};

是真的快,数学真的厉害啊!果然很多搞计算机的人才数学都不差。这个算法复杂度是 O ( l o g n ) O(logn)

猜你喜欢

转载自blog.csdn.net/pjsfirstlaw/article/details/85042317
今日推荐