跟数的划分有些类似,递归+记忆化搜索,
做过数的划分的人做这道题目应该不是很难。
http://www.cnblogs.com/zyxx233/archive/2012/12/08/2809187.html 这是数的划分题解
同样的,我还是以haha来作为函数.....(个人癖好)
状态:haha(s,t,k).
意思是从s到t的数段中加入k 个乘号所能得到的最大值。
所以 ans:=haha(1,n,k).
状态的转移:
for i:=1 to t-k-s+1 do
begin
val(copy(st,s,i),m);
if ha[s+i,t,k-1]<>0 then
haha:=max(haha,m*ha[s+i,t,k-1])
else haha:=max(haha,m*haha(s+i,t,k-1));
end;
当k=0时 haha即为该数段的值。
优化:同数的划分,递归的缺点就是有很多重复的计算,所以我们可以另开一个三维数组来记录每一次函数的值,如果再需计算这个函数,我们先检查这个函数是否已经在数组里记录过了,如
果已经记录,直接调用数组,否则再计算函数。
1 program p1347; uses math;2 var3 i,j,k,l,m,n,ans:longint;4 st:string;5 ha:array[0..60,0..60,0..6]of int64;6 function haha(s,t,k:longint):int64;7 var8 m,n:int64;9 i,j:longint; 10 begin 11 haha:=0; 12 if k<=0 then 13 begin 14 val(copy(st,s,t-s+1),m); 15 haha:=m; 16 end 17 //else if k<0 then exit(0) 18 else if k>0 then 19 for i:=1 to t-k-s+1 do 20 begin 21 val(copy(st,s,i),m); 22 if ha[s+i,t,k-1]<>0 then 23 haha:=max(haha,m*ha[s+i,t,k-1]) 24 else haha:=max(haha,m*haha(s+i,t,k-1)); 25 end; 26 ha[s,t,k]:=haha; 27 end; 28 begin 29 assign(input,'p1347.in'); 30 reset(input); 31 readln(n,k); 32 readln(st); 33 ans:=haha(1,n,k); 34 write(ans); 35 close(input); 36 end.
今天的题解终于写完了!