1. 程式人生 > >動態規劃:乘積最大

動態規劃:乘積最大

問題描述

有一個整數n,將n分解成若干個不同自然數之和,問如何分解能使這些數的乘積最大,輸出這個乘積m

動態規劃

根據題意,對於一個整數n,必然存在一個整數x,使得從n中分解出整數x可以使其最後獲得最大乘積,這要求對n-x的分解也是最優解。我們用dp[i][j]表示從整數i分解出整數j的這種情況下,能達到的最大乘積。那麼dp[i][j]可以遞迴的定義為

dp[i][j]={1max(dp[ij][k]j)i=0j<=i0<=k<j
構造一個二維陣列dp,自底向上計算結果,最後通過查表得到最終結果。

對於給定的整數n,最後的最大乘積為

ans=maxdp[n
][i]0<=i<=n

實現程式碼

#include <cstdio>
#include <iostream>
#include <algorithm>

#define maxn 109
long long dp[maxn][maxn];   //dp[i][j]:從i中分解出j後,能達到的最大乘積

using namespace std;

int solve(int n)
{
    /*賦初始值*/
    for(int i = 0; i <= n; i++)
        dp[0][i] = 1;

    /*根據遞推式構造二維表*/
for(int i = 1; i <= n; i++){ for(int j = 1; j <= i; j++){ for(int k = 0 ; k < j; k++) //找最大值 dp[i][j] = max(dp[i][j], dp[i - j][k] * j); } } /*從表中找出最大值返回*/ long long ans = 0; for(int i = 0; i <= n; i++) ans = max(ans, dp[n][i]); return
ans; } int main() { int n; cin >> n; cout << solve(n) << endl; /*輸出二維陣列dp for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) printf("%4I64d", dp[i][j]); cout << endl; } cout << endl; */ return 0; }