問題描述
設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的數字串,要求選手使用...