一、題目描述
描述給定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...