動態規劃 最大K乘積問題 C 附原始碼 演算法

2021-10-05 22:54:03 字數 2745 閱讀 5980

問題描述

設i是乙個n位十進位制整數。如果將i劃分為k段,則可得到k個整數。這k個整數的乘積稱為i的乙個k乘積。試設計乙個演算法,對於給定的i和k,求出i的最大k乘積。

例如十進位制整數 1234 劃分為 3 段可有如下情形:

1 × 2 × 34 = 68

1 × 23 × 4 = 92

12 × 3 × 4 =144

144即為所求

測試樣例

輸入的第1 行中有2個正整數n和k。正整數n是序列的長度;正整數k是分割的段數。接下來的一行中是乙個n位十進位制整數。(n<=10)

input:

4 21234

output:

144演算法思想

首先我們要明確動態規劃法的思想:

將問題分解為若干子問題,前面一子問題的解可以為後面一子問題的求解提供資訊。在求解任一子問題時,列出所有可能的區域性解,通過比較保留那些有可能達到最優的區域性解,丟棄其他區域性解。依次解決各子問題,直到最後乙個子問題就是初始問題的解。

套用到本問題上,可定義乙個dp二維陣列(我使用的是vector陣列實現,這裡這樣表示更加清晰),定義dp[i][j]為i位數劃分為j段時的最大k乘積,尋找他的最優子問題即可。

為方便理解,假設輸入的數字n為num[1 2 3 4 5 … l],數字表示資料從左數x位的數字… 如312:num[12] = 31。dp[i][j]的子問題即可理解為dp[i-x][j-1]*num[(i-x+1)…i],即比其少乙個劃分,數字位數其小的問題解乘以加上的位數,尋找其中的最大值即可。

即將num[123…x…l]分為兩部分,第一部分為dp[i-x][j-1]最優解,第二部分 為num[(i-x+1)…]。dp[i][j] = max(dp[i-x][j-1]*num[(i-x+1)…i])。

測試結果:

一些想法:

動態規劃法的難點在於如何基於問題、問題的子問題將問題抽象化進而填表,例如本題將最大k乘積問題抽象為乙個dp陣列。如何抽象化,使問題可以擁有迭代結構方便計算最優解,這是個問題。

動態規劃法還有乙個重要的地方是表的初始化,需要給一些已知數用於迭代過程。例如本題輸入1234,dp[i][j]陣列需初始化為

另外在使用stl時發現使用multiset容器vs2017編譯器執行時無法輸出end(),即最後乙個元素,只得使用虛函式改變排列方式,進而得到最大值。

源**:

#define _crt_secure_no_warnings

#include

#include

#include

using

namespace std;

//仿函式

class

mycompare};

//l:num長度,n:分割數,n:輸入的數字

intgetmaxk

(int l,

int n,

int n)

//將n轉化為陣列形式儲存

int n_ = n;

vector<

int>

num(l +1)

;for

(int i = l; i >

0; i--

) num[0]

=0;//計數

vector

int>>

v(l +1)

;//初始化vector陣列

for(

int i =

0; i < v.

size()

; i++

) v[i][1

]= n /

(pow(10

,(l - i)))

;}//填表 v[i][j]為數字前i個分為j段的最大k值 v[i][j] = max(v[i-x][j-1]*num[(i-x)...i])

for(

int i =

1; i <= l; i++

)//使用仿函式使multiset陣列從大到小排列

multiset<

int, mycompare> m;

for(

int x =

1; x < i; x++

)//組合

int nbefore = v[i - x]

[j -1]

* num_b;

m.insert

(nbefore);}

//v[i][j] = max...

v[i]

[j]=

*m.begin()

;}}return v[l]

[n];

}int

main

(void

)

動態規劃之最大K乘積問題

設i是乙個n位十進位制整數。如果將i劃分為k段,則可得到k個整數。這k個整數的乘積稱為i的乙個k乘積。試設計乙個演算法,對於給定的i和k,求出i的最大k乘積。例如十進位制整數 1234 劃分為 3 段可有如下情形 1 2 34 68 1 23 4 92 12 3 4 144 證明滿足最優性原理 假設...

動態規劃法C 實現最大k乘積問題

最大k乘積問題 問題描述 設i是乙個n位十進位制整數。如果將i劃分為k段,則可得到k個整數。這k個整數的乘積稱為i的乙個k乘積。試設計乙個演算法,對於給定的i和k,求出i的最大k乘積。例如十進位制整數 1234 劃分為 3 段可有如下情形 1 2 34 68 1 23 4 92 12 3 4 144...

乘積最大問題 動態規劃

洛谷p1018 今年是國際數學聯盟確定的 2000 世界數學年 又恰逢我國著名數學家華羅庚先生誕辰90周年。在華羅庚先生的家鄉江蘇金壇,組織了一場別開生面的數學智力競賽的活動,你的乙個好朋友xz也有幸得以參加。活動中,主持人給所有參加活動的選手出了這樣一道題目 設有乙個長度為n的數字串,要求選手使用...