动态规划:乘积最大

问题描述

有一个整数n,将n分解成若干个不同自然数之和,问如何分解能使这些数的乘积最大,输出这个乘积m

动态规划

根据题意,对于一个整数n,必然存在一个整数x,使得从n中分解出整数x可以使其最后获得最大乘积,这要求对n-x的分解也是最优解。我们用dp[i][j]表示从整数i分解出整数j的这种情况下,能达到的最大乘积。那么dp[i][j]可以递归的定义为
d p [ i ] [ j ] = { d p [ i ] [ j ] = i               i = j d p [ i ] [ j ] = max ⁡ d p [ i − j ] [ k ] ∗ j        j &lt; = i 且 1 &lt; = k &lt; = i − j dp[i][j] = \begin{cases} dp[i][j] = i\ \ \ \ \ \ \ \ \ \ \ \ \ i = j \\ dp[i][j] = \max {dp[i-j][k] * j} \ \ \ \ \ \ j &lt;= i 且 1&lt;=k&lt;=i-j\\ \end{cases} dp[i][j]={dp[i][j]=i             i=jdp[i][j]=maxdp[ij][k]j      j<=i1<=k<=ij

构造一个二维数组dp,自底向上计算结果,最后通过查表得到最终结果。

对于给定的整数n,最后的最大乘积为
a n s = max ⁡ d p [ n ] [ i ]          0 &lt; = i &lt; = n ans = \max dp[n][i] \ \ \ \ \ \ \ \ 0&lt;=i&lt;=n ans=maxdp[n][i]        0<=i<=n

代码和测试

#include <cstdio>
#include <iostream>
#include <cstring>

#define maxn 109
long long dp[maxn][maxn];   //dp[i][j]:从i中分解出j后,能达到的最大乘积

using namespace std;

int solve(int n)
{
    /*赋初始值*/
    memset(dp, 0, maxn * maxn * sizeof(long long));
    for(int i = 1; i <= n; i++)
        dp[i][i] = i;

    /*根据递推式构造二维表*/
    for(int i = 2; i <= n; i++){
        for(int j = 1; j < i; j++){
            for(int k = 1 ; k <= i-j; k++) //找最大值
                dp[i][j] = max(dp[i][j], dp[i - j][k] * j);
        }
    }

    /*从表中找出最大值返回*/
    long long ans = 0;
    for(int i = 1; i <= n; i++)
        ans = max(ans, dp[n][i]);
    return ans;
}
void test1()
{
    int length = 1;
    int expected = 1;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test2()
{
    int length = 2;
    int expected = 2;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test3()
{
    int length = 3;
    int expected = 3;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test4()
{
    int length = 4;
    int expected = 4;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test5()
{
    int length = 5;
    int expected = 6;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test6()
{
    int length = 6;
    int expected = 9;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test7()
{
    int length = 7;
    int expected = 12;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test8()
{
    int length = 8;
    int expected = 18;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test9()
{
    int length = 9;
    int expected = 27;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test10()
{
    int length = 10;
    int expected = 36;
    cout << expected << "\t\t" << solve(length) << endl;
}

void test11()
{
    int length = 50;
    int expected = 86093442;
    cout << expected << "\t" << solve(length) << endl;
}

int main()
{
    cout << "excetped" << '\t' << "real" << endl;
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
    test7();
    test8();
    test9();
    test10();
    test11();

    return 0;
}

    原文作者:动态规划
    原文地址: https://blog.csdn.net/fd1247/article/details/70146062
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞