LC.343. 整数拆分(DP&数学)

LC.343. 整数拆分(DP&数学)

思路:

一. d p dp 。令 d p [ i ] dp[i] 表示 i i 能分成若干个正整数的最大乘积。

对于第1个数我们可以分成 j [ 1 , i ) j\in[1,i)

显然若第二个数还可以分答案为: j × d p [ i j ] j\times dp[i-j] ,否则为: j × ( i j ) j\times(i-j)

所以状态转移为: d p [ i ] = m a x ( d p [ i ] , j × d p [ i j ] , j × ( i j ) ) dp[i]=max(dp[i],j\times dp[i-j],j\times (i-j))

class Solution {
public:
    int integerBreak(int n) {
        vector<int>dp(n+1,0);
        for(int i=2;i<=n;i++){
            int mx=0;
            for(int j=1;j<i;j++)
                mx=max(mx,max(i-j,dp[i-j])*j);
            dp[i]=mx;
        }
        return dp[n];
    }
};

二.数学做法.

最后答案可能的情况。

1.答案不可能含有 x > 4 x>4 的数,因为当 x > 4 x>4 时, x x 显然可以分成两个乘积比和大的数,比如 2 ( x 2 ) > x 2(x-2)>x ,对于 x = 4 x=4 ,也可以用 2 × 2 2\times 2 代替,即答案不含有 x > 3 x>3 的数。

2.当 n > 4 n>4 时,答案不含1,因为这个 1 1 显然可以加到其他数上使答案更大。

3. n > 4 n>4 时, 2 2 的个数小于 3 3 个,因为 3 3 个2可以换成 2 2 个3。

4. n 4 n\le4 时,显然答案为 n 1 n-1

扫描二维码关注公众号,回复: 11487922 查看本文章

因此我们只需特判 2 2 的个数是多少个,剩下的都是3即可。

n % 3 = = 0 n\% 3==0 显然全为3.

n % 3 = = 2 n\%3==2 ,显然只有一个2.

n % 3 = = 1 n\%3==1 ,显然要拿出一个 3 3 ,凑成两个2.

class Solution {
public:
    int integerBreak(int n) {
        if(n<4) return n-1;
        int x=n/3,y=n%3;
        if(!y) return pow(3,x);
        else if(y==2) return pow(3,x)*2;
        else return pow(3,x-1)*4;
    }
};

三.由数学做法,我们显然可以优化 d p dp 过程,特判 n < 4 n<4 ,将 j j 改为 2 , 3 2,3 即可。

class Solution {
public:
    int integerBreak(int n) {
        if(n<4) return n-1;
        vector<int>dp(n+1,0);dp[2]=1;
        for(int i=3;i<=n;i++)
                dp[i]=max({2*(i-2),2*dp[i-2],3*(i-3),3*dp[i-3]});
        return dp[n];
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107681229
今日推荐