/***題目內容:
設I是一個n位十進制整數.如果將I划分為k段,則可得到k個整數.這k個整數的乘積稱為I的一個k乘積.試設計一個算法,對於給定的I和k ,求出I的最大k乘積.
Input
輸入的第1行中有2個正整數n和k.正整數n是序列的長度;正整數k是分割的段數.接下來的一行中是一個n位十進制整數.(n<=10)
Output
輸出計算結果,第1行中的數是計算出的最大k乘積.
n位十進制整數.(n<=10)
輸入描述
輸入的第1行中有2個正整數n和k.正整數n是序列的長度;正整數k是分割的段數.接下來的一行中是一個n位十進制整數.(n<=10)
輸出描述
輸出計算結果,第1行中的數是計算出的最大k乘積.***/
繼續做做回溯的經典例子:
下面是用遞推做的,(里面都是for循環枚舉)
其中兩個二維數組 ,一個數組存儲從第幾位到第幾位的這一串數字,另一個數組儲存前i位分成j段 乘積的最大值。
思路是,先把每位到每位的數字存儲下來,然后再枚舉前i位 ,枚舉前位中分成j段,枚舉一個乘號的位置來確定最大乘積並存儲下來
最后全找前i位分成j段的最大乘積,直接取數就行了。
#include <iostream> using namespace std; int dp[100][100]; int m[100][100]; int main(){ int n, k, a; cin >> n >> k >> a; if(k == 1){//如果這個數分成一段,就直接輸出這個數。 cout << a; return 0; } int b = 1, q = 1; for(int i = n; i >= 1; i--){// int p = 10; b = a / q; q *= 10; // cout << b << endl; for(int j = i; j >= 1; j--){//從第幾位到第幾位每段數字是多少全記錄下來 m[j][i] = b % p; p *= 10; // cout << m[j][i] << " "; } } // dp[1][1] = a; for(int i = 1; i <= n; i++){ //枚舉前n個數字 for(int j = 1; j <= i; j++){ //枚舉乘號的個數//分成多少段 if(j == 1){ dp[i][j] = m[1][i];//前i個分成j段 continue; } for(int nn = 1; nn < i; nn++)//枚舉乘號的位置 dp[i][j] = max(dp[i][j], dp[nn][j-1]*m[nn+1][i]); } } cout << dp[n][k]; return 0; }