饿…… 上次考这道题一直是215错误。直到今天看了下准轩的代码才发现是过程中数据类型开小了。虽然看着才8*8的方格,但是longint都不够。看来以后做题在这方面要多加小心啊!
此题乍看貌似是搜索题,由于棋盘大小固定是8行8列。枚举所有的切割可能性。。然后发现以我的水平还无法去实现。。
然后发现题目中一句话说的切割必须要沿着棋盘格子的边进行。貌似dp。。。
然后再发现研究它的状态方程其实可以表示为d[i,棋盘大小] = min( d[i-1,切割1刀后的某部分棋盘大小] + d[1,切割1刀后棋盘剩余的部分] )
]其中d[i,棋盘大小
表示的是当棋盘切割i刀后得到((均方差最小值)^2)*n的最小值
边界状态即为d[1,棋盘大小]=(棋盘大小总分-平均值avg)^2
具体方程请参见《算法艺术与信息学竞赛》(刘汝佳)p116
通过方程我们可以看出平均值其实是一定值为(棋盘总分)/n。。
最后结果只需输出d[n,1,1,8,8]/n-sum*sum/n/n即可。
var
i,j,k,n,h,total,xx1,yy1,xx2,yy2:longint;
m:int64;
costsum:array[1..8,1..8,1..8,1..8]of longint;
d:array[-1..20,-1..10,-1..10,-1..10,-1..10]of int64;
cost:array[-1..10,-1..10]of int64;
re:real;
function min(s1,s2:int64):int64;
begin if s1<s2 then min:=s1 else min:=s2; end;
begin
assign(input,'chess.in');
reset(input);
assign(output,'chess.out');
rewrite(output);
readln(n);
fillchar(costsum,sizeof(costsum),0);
for i:=1 to 8 do
for j:=1 to 8 do
read(cost[i,j]);
for xx1:=1 to 8 do
for yy1:=1 to 8 do
for xx2:=xx1 to 8 do
for yy2:=yy1 to 8 do
begin
total:=0;
for i:=xx1 to xx2 do
for j:=yy1 to yy2 do
total:=total+cost[i,j];
costsum[xx1,yy1,xx2,yy2]:=total;
d[1,xx1,yy1,xx2,yy2]:=total*total;
end;
for k:=2 to n do
for xx1:=1 to 8 do
for yy1:=1 to 8 do
for xx2:=xx1 to 8 do
for yy2:=yy1 to 8 do
begin
m:=maxlongint;
for i:=xx1 to xx2-1 do
m:=min(m,min(d[k-1,xx1,yy1,i,yy2]+d[1,i+1,yy1,xx2,yy2],d[k-1,i+1,yy1,xx2,yy2]+d[1,xx1,yy1,i,yy2]));
for j:=yy1 to yy2-1 do
m:=min(m,min(d[k-1,xx1,yy1,xx2,j]+d[1,xx1,j+1,xx2,yy2],d[k-1,xx1,j+1,xx2,yy2]+d[1,xx1,yy1,xx2,j]));
d[k,xx1,yy1,xx2,yy2]:=m;
end;
re:=sqrt(d[n,1,1,8,8]/n-costsum[1,1,8,8]*costsum[1,1,8,8]/n/n);
writeln(re:0:3);
close(input);
close(output);
end.
终于完美解决了。以后一定要注意小错误啊!