vijos p1038(添加括号(石子合并))

 

一道动态规划的题目。

区间动规?我不知道......

第一次接触这种类型的动规,区间动规吧...

就是石子合并。

方程:

F[i,j] = min{F[i,k] + F[k + 1,j] + c[i,j] | i <= k < j}。

我们可以用递推的方法实现它,但是如何递推是个问题。

自然而然地,先求得长度为1的区间,然后是长度为2的区间,然后3.....

至于添括号的方法和各个中间和,我们可以用两个字符串数组来处理他们。

具体看代码:

 1 program p1038; uses math;
 2 var
 3         i,j,k,l,m,n,ans:longint;
 4         s:array[0..30]of longint;
 5         st:string;
 6         c,d,f:array[0..30,0..30]of longint;
 7         st1,st2:array[0..30,0..30]of string;
 8 {function haha(a,b:longint):longint;
 9 var
10         i,j,k:longint;
11 begin
12         if b-a=1 then haha:=a+b
13         else
14         begin
15         haha:=min(haha(a+1,b),haha(a,b-1))+c[a,b];
16         end
17 end;}
18 begin
19         assign(input,'p1038.in');
20         reset(input);
21         fillchar(c,sizeof(c),0);
22         fillchar(f,sizeof(f),0);
23         read(n);
24         for i:=1 to n do read(s[i]);
25         for i:=1 to n do
26                 for j:=1 to i-1 do
27                         for l:=j to i do
28                                 c[j,i]:=c[j,i]+s[l];
29         for i:=1 to n do
30                 c[i,i]:=s[i];
31         for i:=1 to n do
32                 for j:=1 to n do
33                         f[i,j]:=maxlongint;
34         for i:=1 to n do
35                 f[i,i]:=0;
36         for i:=1 to n do
37                 str(s[i],st2[i,i]);//对中间和预处理
38         for i:=1 to n-1 do
39                 for j:=1 to n-i do
40                         for k:=j to j+i-1 do
41                                 begin
42                                 if f[j,j+i]>=f[j,k]+f[k+1,j+i]+c[j,j+i] then
43                                         begin
44                                         str(c[j,j+i],st);
45                                         st1[j,j+i]:=st1[j,k]+st1[k+1,j+i]+' '+st;//各个中间和
46                                         st2[j,j+i]:='('+st2[j,k]+'+'+st2[k+1,j+i]+')';//添括号的方法
47                                         end;
48                                 f[j,j+i]:=min(f[j,j+i],f[j,k]+f[k+1,j+i]+c[j,j+i]);
49                                 end;
50         writeln(st2[1,n]);
51         writeln(f[1,n]);
52         delete(st1[1,n],1,1);
53         writeln(st1[1,n]);
54         close(input);
55 end.                 

 

posted @ 2012-12-04 21:58  改名字干什么  阅读(268)  评论(0编辑  收藏  举报