最大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
程式設計任務
對於給定的i 和k,程式設計計算i 的最大k 乘積。
資料輸入
輸入的第1 行中有2個正整數n和k。正整數n是序列的長度;正整數k是分割的段數。接下來的一行中是乙個n位十進位制整數。(n<=10)
結果輸出
計算出的最大k乘積。
輸入檔案示例 輸出檔案示例
input.txt output.txt
3 2312 62
問題分析
首先用反證法證明最大k乘積問題具有最優子結構性質,從而證明該題目適合使用動態規劃法:
(1)假設n位十進位制整數i的最大k乘積記為f(n,k),前k-1段總共是m位,且1<=mf(m,k-1), 左右兩邊同時乘以i(m,n-m)得h(m,k-1)*i(m,n-m)>f(m,k-1)*i(m,n-m)=f(n,k) 即f(n,k)不是i的最大k乘積與最初的假設相矛盾。
(3)所以f(m,k-1)是前面m位十進位制整數的最大k-1乘積,即最大k乘積問題具有最優子結構性質。這說明可以使用動態規劃來求解。
演算法步驟:
(1)1.1設temparr(h,k) 表示: 從第h位到第k位所組成的十進位制數
1.2設dp(i,j)表示前i位(1-i)分成j段所得的最大乘積,
1.3arr陣列儲存給定的n個數字 ;
1.4首先將連續數字第i位到第j位表示的十進位制數放在temparr陣列,dp[i][j]代表前i位有j個乘號。
(2)寫出動態方程:
如果只分成一段,那麼dp[i][1]=temparr[1][i];
否則: 前i位(1~i)數字分j組乘積的最大值等於分為j-1組的結果再乘以乙個後面剩下的數字組成所代表的的十進位制數。
dp[i][j]=max(dp[i][j],dp[k][j-1]*temparr[k+1][i]); 1<=k#include
#include
#include
#include
#include
#include
#define max 20
using
namespace std;
//數字的位數
int n =0;
//分成k段
int k =0;
//給定的數字
int value =0;
//儲存給定陣列的每乙個數字
int* arr =
null
;//儲存k乘積最大值
int arr2d[max]
[max]
;//臨時存放第i個到第j個數字表示的十進位制數
int temparr[max]
[max];/*
讀取給定的data.txt檔案的資料
讀取第一行的n , k
第二行的數字 並將每乙個陣列儲存到arr陣列中
*/void
readtextdata()
else
else
if(count ==1)
else
if(count ==2)
else
fla =
true
;break;}
}}}if
(fla ==
true)}
cout <<
"輸入的資料為:"
;for
(int i =
0; i < n; i++
) cout << endl;
ifs.
close()
;}else}/*
@to do:將讀取到的value從第i個到第j個數字表示的十進位制值儲存到乙個陣列中
*/void
init()
for(
int i =
1; i <= n; i++)}
}int
getvalue()
//列舉乘號位置
for(
int k =
1; k < i; k++)}
}//返回最終結果
return arr2d[n]
[k-1];
}int
main()
當data.txt檔案輸入為:
輸出結果:
實驗分析:
根據演算法我們知道使用了乙個一維陣列arr,兩個二維陣列temparr和dp,所以該演算法的空間複雜度為o(nn),在函式init()初始化過程中,使用了兩個巢狀的for迴圈,時間複雜度為o(nn),在getvalue()函式中,使用了三個for迴圈,時間複雜度為o(nnn),所以該演算法的時間複雜度為o(nnn)
TSP問題,動態規劃法
tsp問題是指旅行家要旅行n個城市,要求各個城市經歷且僅經歷一次然後回到出發城市,並要求所走的路程最短。各個城市間的距離可以用代價矩陣來表示。假設從頂點i出發,令d i,v 表示從頂點i出發經過v 中各個頂點一次且僅一次,最後回到出發點i的最短路徑長度,開始時,v v 於是,tsp問題的動態規劃函式...
動態規劃法求解TSP問題 C
此文章借鑑於博文在此基礎上重新進行了分析總結。1 怎麼求頂點子集,即這些怎麼記錄?答 例如4個頂點,依次為 十進位制數0 1 2 3 4 5 6 7的二進位制分別為000 001 010 011 100 101 110 111。上述集合中的元素即為二進位制中的位數,例如集合,可用二進位制110 十進...
動態規劃法求最大子段和問題C
給定由n個整數組成的序列 a1,a2,an 求該序列形如 ai,ai 1,ai 2,ai n 的子段和的最大值,當所有整數均為負整數時,其最大子段和為0。依此定義,所求的最優值為 include include using namespace std int maxsum int a,int b,i...