日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态规划|最大k乘积问题(C语言)

發布時間:2023/12/19 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态规划|最大k乘积问题(C语言) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目:

【分析】
先通過若干個簡單例子來觀察規律,摸索思路。例如十進制整數 1234 劃分為 3 段可有如下情形:
1 × 2 × 34 = 68
1 × 23 × 4 = 92
12 × 3 × 4 = 144(滿足要求的解)

以計算正整數 1234 的最大 3 乘積為例,即 I = 1234,n = 4,k = 3(將 1234 分為 3 段)。由于計算乘積時要使用整數中的“一段”數字,則定義 w(s,t) 表示 I 中從第 s 位到第 t 位組成的數,如 w(2,3)=23;按照動態規劃算法處理問題的步驟,定義 m(i,j) 表示整數 I 的前 i 位分成 j 段所得的“最大 j 乘積”,顯然所求的問題即為計算 m(n,k)。
根據上述定義,顯然有:
(1)當 i < j 時(這種情況下整數 I 的前 i 位無法分成 j 段),定義 m(i,j) = 0;
(2)當 j = 1 時(分為 1 段),有 m(i,j) = m(i,1) = w(1,i);
(3)當 j > 1且 j <= i 時,從 I 中的前 d 位數字(d 從 1 循環到i-1)可得到“最大 j-1 乘積(即 j-1 分段)”,然后乘以剩下的數字(組成 1 段,為 w(d+1,i),即從 d+1 位開始,到 I 的第 i 位),寫成狀態方程即為:

計算過程中會建立 2 個二維數組 W 和 M,前者是 n x n 陣,儲存w(s,t) 的值(表示 I 中從第 s 位到第 t 位組成的數);后者是 n x k 陣,儲存 m(i,j) 的值 。以計算正整數 1234 的最大 3 乘積為例,即 I = 1234,n = 4,k = 3,則有:

綜上,可得m(i,j)的遞推關系如下:

代碼:

// 使用的庫定義 #include <stdio.h> #include <stdlib.h> #include <string.h>// ######################################################################## // // // // 下面是數據定義區 // // // // ######################################################################## //#define STR_LEN 100 #define TRUE 1 #define FALSE 0//// ######################################################################## // // // // 下面是各個子函數定義 // // // // ######################################################################## //int CalcMaxKProduct( int n, int k, int **D, int **P ); //計算正整數的最大 k 乘積 void PrintProductMatrix( int n, int k, int **D, int **P );//顯示計算數據 //// ######################################################################## // // // // 下面是各個子函數的實現 // // // // ######################################################################## //// 使用動態規劃法計算兩個字符串之間的編輯距離 ... // // 測試數據如下 : // ( 1 ) 1234 劃分為 3 段 : 12 * 3 * 4 = 144 // ( 2 ) 自行設計 2 個測試用例 int CalcMaxKProduct( int n, int k, int **D, int **P ) {int i, j, t, maxv, tk;//當i<j無法進行分段 for(i = 1;i <= n;i++) //分成一段 j=1 {P[i][1]= D[1][i];}for(i = 1; i <= n;i++) //DP過程 {for(j = 2;j <= i;j++) //當 j > 1且 j <= i 時,從 I 中的前 t 位數字(t 從 1 循環到i-1)可得到“最大 j-1 乘積(即 j-1 分段) {maxv = 0;for(t = 1;t < i;t++){if((tk = P[t][j-1]*D[t+1][i]) > maxv) //然后乘以剩下的數字(組成 1 段,為 D(t+1,i),即從 t+1 位開始,到 I 的第 i 位), maxv = tk;}P[i][j] = maxv;}}return P[n][k]; }// 打印編輯距離矩陣 ... void PrintProductMatrix( int n, int k, int **D, int **P ) {int i, j;// 打印 'D' ...printf( "\t生成的整數分段值矩陣為 : \n" );for(i=1 ; i<= n; i++){for(j=1 ; j<= n; j++){printf("%d ",D[i][j]);printf(" ");} printf("\n");}printf( "\n\n" );// 打印 'P' ...printf( "\t生成的分段乘積矩陣為 : \n" );for(i=1 ; i<= n; i++){for(j=1 ; j<= k; j++){printf("%d ",P[i][j]);printf(" ");}printf("\n"); }printf( "\n\n" ); }//// ######################################################################## // // // // 下面是主程序的實現 // // // // ######################################################################## //int main() {char StrI[ STR_LEN ];char StrK[ STR_LEN ];int *I, n; // 儲存輸入的整數及其長度 ...int k; // 輸入的整數分為 'k' 段 ...int **D, **P; // 二維數組, 儲存整數的各個分段值及乘積值 ...int i, j, MaxProduct;int IsStop;IsStop = FALSE;while ( !IsStop ){// 清屏 ...system( "cls" );// 輸入整數 'I' ...printf( "\n\n\t請輸入 < 整數 I 的值 > , 輸入 < q / Q > 表示結束 : " );scanf( "%s", StrI );n = strlen( StrI ); // 輸入整數的位數 ...if ( n > 0 )IsStop = ( ( StrI[ 0 ] == 'q' ) || ( StrI[ 0 ] == 'Q' ) );elseprintf( "\t輸入的整數不能為空 !\n\n" );if ( !IsStop ){// 輸入分段數 'k' ...printf( "\n\t請輸入 < 整數分段數 k > , 輸入 < q / Q > 表示結束 : " );scanf( "%s", StrK );if ( strlen( StrK ) > 0 )IsStop = ( ( StrK[ 0 ] == 'q' ) || ( StrK[ 0 ] == 'Q' ) );elseprintf( "\t輸入的整數分段數不能為空 !\n\n" );// 輸入的整數及其分段數 'I' 和 'k' 均不為空, 則計算最大 'k' 乘積 ...if ( !IsStop ){// 將輸入的字符串轉換為整數 ...// 輸入的整數 'I' ...// 動態申請一維數組 ...I = ( int * )malloc( ( n + 1 ) * sizeof( int ) );// 將輸入的字符串整數的每一位放入 'I' 中 ...for ( i = 1; i <= n; i++ )I[ i ] = StrI[ i - 1 ] - '0'; // 注意序號起始值 ...// 輸入的分段數 'k' ...k = atoi( StrK ); //把StrK(字符串)轉換為一個整數 // 動態申請二維數組 'D' 和 'P' ...// 'D' - 儲存整數的各個分段值( n x n 陣 ) ...//定義 D(s,t) 表示 I 中從第 s 位到第 t 位組成的數 D = ( int ** )malloc( ( n + 1 ) * sizeof( int ) );for ( i = 0; i <= n; i++ )D[ i ] = ( int * )malloc( ( n + 1 ) * sizeof( int ) );// 初始化 ...for ( i = 0; i <= n; i++ )for ( j = 0; j <= n; j++ )D[ i ][ j ] = 0;// 'P' - 儲存整數的分段乘積值( n x k 陣 ) ...//定義 P(i,j) 表示整數 I 的前 i 位分成 j 段所得的“最大 j 乘積” P = ( int ** )malloc( ( n + 1 ) * sizeof( int ) );for ( i = 0; i <= n; i++ )P[ i ] = ( int * )malloc( ( k + 1 ) * sizeof( int ) );// 初始化 ...for ( i = 0; i <= n; i++ )for ( j = 0; j <= k; j++ )P[ i ][ j ] = 0;// 生成 'D' 矩陣 ...//表示 I 中從第 s 位到第 t 位組成的數 for( i = 1 ;i <= n; i++ ){D[i][i] = I[i];for(j = i+1;j <= n;j++){D[i][j] = D[i][j-1]*10+I[j]; }}// 計算最大 'k' 乘積 ...MaxProduct = CalcMaxKProduct( n, k, D, P );// 顯示計算結果 ...printf( "\n\t< 計算得到的最大 k 乘積為:%d > \n\n", MaxProduct );// 打印數值矩陣 ...PrintProductMatrix( n, k, D, P );// 釋放二維數組 'D' 和 'P' 的空間 ...for ( i = 0; i <= n; i++ )free( D[ i ] );free( D );for ( i = 0; i <= n; i++ )free( P[ i ] );free( P );// 等待用戶輸入任意一鍵返回 ...printf( "\n\n" );system( "PAUSE" );}}}// 等待用戶輸入任意一鍵返回 ...printf( "\n\n" );return 0; }//

運行結果:

總結

以上是生活随笔為你收集整理的动态规划|最大k乘积问题(C语言)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。