一、試題
有乙個由數字1,2,... ,9組成的數字串(長度不超過200),問如何將m(m<=20)個加號("+")插入到這個數字串中,使所形成的算術表示式的值最小。請編乙個程式解決這個問題。
注意:加號不能加在數字串的最前面或最末尾,也不應有兩個或兩個以上的加號相鄰。
m保證小於數字串的長度。
例如:數字串
79846
,若需要加入兩個加號,則最佳方案為
79+8+46
,算術表示式的值
133。
[輸入格式]
從鍵盤讀入輸入檔名。數字串在輸入檔案的第一行行首(數字串中間無空格且不折行),m的值在輸入檔案的第二行行首。
[輸出格式]
在螢幕上輸出所求得的最小和的精確值。
輸入示例
82363983742
3輸出示例
2170
二、分析
這道題目是經典的動態規劃的題目
.因此肯定採用動態規劃.
考慮到資料的規模超過了長整型
,我們注意在解題過程中採用高精度演算法.
規劃方程
:f[i,j] = min (i-1<=k<=j-1)
邊界值:f[0,i] := num[1,i];
f[i,j]
表示前j
個數字中添上
i個加號後得到的最小值。
num[i,j]
表示數字串第
i位到第
j位的數
程式需要的空間約為
20 * 200 * 200.
顯然難以承受。
但是,還能更優。每一步,我們都只與上一步有關。因此可以採用滾動陣列,這樣,複雜度就降到了
2 * 200 * 200
左右了。
程式的時間效率約為
20 * 200 * 200.
時間上根本不成問題。
這道題目看起來很容易
,但是如果在程式設計時不多加細心,容易的問題也難免會有這樣那樣的錯誤。因此
,越是簡單的題目越要細心,不能粗枝大葉。
三、參考程式
program noi96_4;
const
filein='input.txt';
fileou='output.txt';
type
stype=string[202];
varf1 , f2:array[1..200] of ^stype;
st:string;
fi,fo:text;
n , m:integer;
procedure init;
vari , j , k : integer;
begin
assign(fi,filein);
assign(fo,fileou);
reset(fi);
rewrite(fo);
readln(fi,st);
n := length(st);
readln(fi,m);
close(fi);
for i := 1 to 200 do
begin new(f1[i]);fillchar(f1[i]^,sizeof(f1[i]^),'0');end;
for i := 1 to 200 do
begin new(f2[i]);fillchar(f1[i]^,sizeof(f1[i]^),'0');end;
for i := 1 to n do
f1[i]^ := copy(st,1,i);
end;
function big(st1,st2:string):boolean;
begin
big := ( length(st1)>length(st2) ) or
( length(st1)=length(st2) ) and ( st1 > st2 );
end;
procedure sum(st1,st2:string;var st3:string);
vari , j , k, l , o , p : integer;
begin
st3 := '';
while length(st1)
while length(st2)
p := 0;
for o := length(st1) downto 1 do
begin
val(st1[o],i,l);
val(st2[o],j,l);
k := (i+j+p) mod 10;
p := (i+j+p) div 10;
st3 := chr(k+48) + st3;
end;
if p>0 then st3 := chr(p+48) + st3;
while (st3[1]='0') and (length(st3)>1) do delete(st3,1,1);
end;
procedure dynamic;
vari, j , k , l , o , p: integer;
st1 , st2 , st3: string;
begin
for i := 1 to m do
begin
for j := 1 to 200 do
fillchar(f2[j]^,sizeof(f2[j]^),'0');
for j := i+1 to n-m+i do
for k := i to j-1 do
if (k >= i) and ( k < j ) and(j-k<=101) then
begin
sum(f1[k]^,copy(st,k+1,j-k),st3);
if big(f2[j]^,st3) or (f2[j]^='0') then
f2[j]^ := st3;
end;
for j := 1 to 200 do
f1[j]^ := f2[j]^;
end;
end;
begin
init;
dynamic;
writeln(fo,f1[n]^);
close(fo);
end.
添柴 12014 括號匹配 解題報告
題目描述 id 12014 括號匹配 標籤 資料結構 棧詳情 在程式設計當中我們只會用到三種括號 圓括號 方括號和花括號 編譯器在編譯的時候會檢查括號是否正確匹配。例如 都是合法的匹配。但是 則是不合法的匹配。請編寫乙個程式來判斷輸入的括號序列是否合法。輸入格式 只有一行,為 組成的序列,長度不超過...
leetcode 921 使括號有效的最少新增 棧
描述 給定乙個由 和 括號組成的字串 s,我們需要新增最少的括號 或是 可以在任何位置 以使得到的括號字串有效。從形式上講,只有滿足下面幾點之一,括號字串才是有效的 它是乙個空字串,或者 它可以被寫成 ab a 與 b 連線 其中 a 和 b 都是有效字串,或者 它可以被寫作 a 其中 a 是有效字...
LeetCode921 使括號有效的最少新增
給定乙個由 和 括號組成的字串 s,我們需要新增最少的括號 或是 可以在任何位置 以使得到的括號字串有效。從形式上講,只有滿足下面幾點之一,括號字串才是有效的 它是乙個空字串,或者 它可以被寫成 ab a 與 b 連線 其中 a 和 b 都是有效字串,或者 它可以被寫作 a 其中 a 是有效字串。給...