[bzoj1032]祖玛
压缩一下块,然后区间dp。
左右两边合并的时候的代价是是否加起来大于2。(是否需要再插入一个球)

1 uses math; 2 var _color:array[0..1000] of Longint; 3 _tot:array[0..1000] of Longint; 4 src:array[0..1000] of Longint; 5 f:array[0..1000] of array[0..1000] of Longint; 6 i,j,k,n,lastColor,tot,num:Longint; 7 8 begin 9 fillchar(f,sizeof(f),$3f); 10 readln(n); 11 for i:=1 to n do read(src[i]); 12 lastColor:=src[1]; 13 for i:=1 to n do 14 begin 15 if lastColor<>src[i] then 16 begin 17 inc(num); 18 _color[num]:=lastColor; 19 _tot[num]:=tot; 20 tot:=1; 21 lastColor:=src[i]; 22 end 23 else inc(tot); 24 end; 25 inc(num); 26 _color[num]:=lastColor; 27 _tot[num]:=tot; 28 for i:=1 to num do 29 begin 30 if _tot[i]=1 then 31 f[i][i]:=2 32 else 33 f[i][i]:=1; 34 end; 35 for i:=2 to num do 36 for j:=1 to num-i+1 do 37 begin 38 if _color[j]=_color[j+i-1] then 39 begin 40 if _tot[j]+_tot[j+i-1]=2 then k:=1 41 else k:=0; 42 f[j][j+i-1]:=f[j+1][j+i-2]+k; 43 end; 44 for k:=1 to i-1 do 45 f[j][j+i-1]:=min(f[j][j+i-1],f[j][j+k-1]+f[j+k][j+i-1]); 46 end; 47 writeln(f[1][num]); 48 end.