POJ1390 Blocks——动态规划——pku1390

经典的动态规划,LRJ神牛的书上经典例题第一题。

开一个三维数组,f[i][j][k]表示将i~j这一段,连上后面的k个格子全部消去所能够获得的最大价值。

状态转移方程:

f[i][j][k]=Max{

          Max{f[i][p][len[j]+k]+f[p+1][j-1][0]}(color[p]=color[j] and i<p<j)//和前面某段一起消掉

          f[i][j-1][0]+sqr(len[j]+k)//马上消掉这一段

       }

其中,len[i]表示第i段连续区间的长度,比如说样例1中的len值分别为1,4,3,1

代码很简单:

Program POJ1390;//By_Thispoet

Const

	maxn=200;

Var

	i,j,k,m,n,l,r,p,o,q						:Longint;

	f										:Array[0..maxn,0..maxn,0..maxn]of Longint;

	len,color,maxr,rep						:Array[1..maxn]of Longint;

	rpos									:Array[1..maxn]of Integer;

	rec										:Array[1..maxn,0..maxn]of Longint;

	

Function Max(i,j:Longint):Longint;

begin

	if i>j then exit(i);exit(j);

end;





BEGIN



	readln(o);

	q:=o;

	while o>0 do

		begin	



			n:=0;l:=0;

			fillchar(rpos,sizeof(rpos),0);

			fillchar(rec,sizeof(rec),0);

			fillchar(len,sizeof(len),0);

			readln(r);

			for i:=1 to r do

				begin

					read(m);

					if l=m then inc(len[n]) else

						begin

							inc(n);

							inc(rec[m,0]);rec[m,rec[m,0]]:=n;

							rep[n]:=rec[m,0];

							color[n]:=m;len[n]:=1;

						end;

					l:=m;

				end;

			for i:=n downto 1 do

				begin

					maxr[i]:=rpos[color[i]];

					inc(rpos[color[i]],len[i]);

				end;



			//prepare



			fillchar(f,sizeof(f),0);

			for i:=1 to n do

				for k:=0 to maxr[i] do

					f[i,i,k]:=sqr(len[i]+k);

			for j:=1 to n-1 do

				for i:=1 to n-j do

					for k:=0 to maxr[i+j] do

						begin

							f[i,i+j,k]:=f[i,i+j-1,0]+sqr(len[i+j]+k);

							l:=rep[i+j]-1;

							while l>0 do

								begin

									p:=rec[color[i+j],l];

									if p<i then break;

									f[i,i+j,k]:=Max(f[i,i+j,k],f[i,p,k+len[i+j]]+f[p+1,i+j-1,0]);

									dec(l);

								end;

						end;



			writeln('Case ',q-o+1,':',' ',f[1,n,0]);



			dec(o);

			

		end;



END.

你可能感兴趣的:(block)