最佳加法表示式(動態規劃)

2021-10-04 12:56:18 字數 3438 閱讀 1305

一、題目描述

描述

給定n個1到9的數字,要求在數字之間擺放m個加號(加號兩邊必須有數字),使得所得到的加法表示式的值最小,並輸出該值。例如,在1234中擺放1個加號,最好的擺法就是12+34,和為36

輸入

有不超過15組資料

每組資料兩行。第一行是整數m,表示有m個加號要放( 0<=m<=50)

第二行是若干個數字。數字總數n不超過50,且 m <= n-1

輸出對每組資料,輸出最小加法表示式的值

樣例輸入

2123456

1123456

412345

樣例輸出

102579

15

提示

要用到高精度計算,即用陣列來存放long long 都裝不下的大整數,並用模擬列豎式的辦法進行大整數的加法。

二、問題分析

將m個加號插入到n個數中,求能得到的最小表示式結果。可以先考慮把最後乙個加號插入到某個數之後,該數一定在m到n-1之間,因為剩餘m-1個加號至少需要m個數來放置,所以最後乙個加號的位置必然在m之後,毫無疑問最後乙個加號最多放在倒數第二個數(n-1)之後。

將最後乙個加號放到第k個數之後形成的表示式值由兩部分組成:

(1)前m-1個加號放到前k個數中形成得到的表示式值 minval(m-1,k)

(2)第k+1字元到最後乙個字元組成的數值,num(k+1,n)

沒有加號時,結果只由第二部分組成

所以最小加法表示式minval(m,n) = min ( k = m … n-1)

三、源**

1.先給出我的非高精度演算法,主要看思路

// 最佳加法表示式,非高精度版

//#include

#include

#include

#include

using

namespace std;

intmain()

}memset

(minval,

0x3f

,sizeof

(minval));

for(

int i =

1; i <= m;

++i)

//i 個 加號

} cout << minval[m]

[n]<}return0;

}

2.然後是高精度演算法

申明 以下兩種方法** 郭怡柔,個人認為第一種思路比較順暢,易於理解

第一種思路,定義乙個高精度數的類,以及該類的+、<、<<,

同時定義從字串轉為數值的方法

#include

#include

#include

using

namespace std;

struct bigint

else

carry =0;

}if( carry ==1)

else

result.len = ml;

return result;

}bool

operator

<

(const bigint & n)

return

false;}

}bigint()

bigint

(const

char

* n,

int l)};

ostream &

operator

<<

(ostream & o,

const bigint & n)

const

int maxn =60;

char a[maxn]

;bigint num[maxn]

[maxn]

;//num[i][j]表示從第i個數字到第j個數字所構成的整數

bigint v[maxn]

[maxn]

;//v[i][j]表示i個加號放到前j個數字中間,所能得到的最佳表示式的值。

intmain()

for(

int j =

1; j <= n;

++j)

for(

int i =

1;i <= m;

++i)

v[i]

[j]= tmpmin;}}

} cout << v[m]

[n]<< endl;

}return0;

}

第二種思路定義兩個字串的加法與比較運算

#include

#include

#include

using

namespace std;

struct bigint

else

carry =0;

}if( carry ==1)

else

result.len = ml;

return result;

}bool

operator

<

(const bigint & n)

return

false;}

}bigint()

bigint

(const

char

* n,

int l)};

ostream &

operator

<<

(ostream & o,

const bigint & n)

const

int maxn =60;

char a[maxn]

;bigint num[maxn]

[maxn]

;//num[i][j]表示從第i個數字到第j個數字所構成的整數

bigint v[maxn]

[maxn]

;//v[i][j]表示i個加號放到前j個數字中間,所能得到的最佳表示式的值。

intmain()

for(

int j =

1; j <= n;

++j)

for(

int i =

1;i <= m;

++i)

v[i]

[j]= tmpmin;}}

} cout << v[m]

[n]<< endl;

}return0;

}

參考**:

動態規劃 最佳加法表示式

總時間限制 1000ms 記憶體限制 65536kb 描述 給定n個1到9的數字,要求在數字之間擺放m個加號 加號兩邊必須有數字 使得所得到的加法表示式的值最小,並輸出該值。例如,在1234中擺放1個加號,最好的擺法就是12 34,和為36 輸入有不超過15組資料 每組資料兩行。第一行是整數m,表示...

動態規劃之最佳加法表示式

有乙個由1.9組成的數字串.問如果將m個加號插入到這個數字串中,各種可能形成的表示式中,值最小的那個表示式的值是多少?假設數字串的長度為n,有m個括號,插入的所有可能性為n m 如果要把所有可能性全部計算出來再找出最小值,這樣計算的時間複雜符是巨大的。換乙個角度思考,從後往前來看 若最後乙個加號新增...

Python 動態規劃 最佳加法表示式

輸入乙個數字組成的字串,給m個加號,將所有加號任意放在字串中中某位置,要求最終得到的加法表示式的結果最小。輸入 2 123456 輸出 135 我們用加號的個數作為迭代的依據。建立兩個二維陣列。第乙個是cur min m n 表示將m個 號放入前n個數字中。根據加法式子的構成我們可以得到兩個條件。1...