100%的数据 1<=n<=500,1<=k<=n
核心代码:
for i:=1 to n do
for j:=2 to i do//每一个马厩内至少要有一匹马,所以j(马厩的数量)最多是i个
begin
f[i,j]:=maxint;
for k:=j-1 to i-1 do//由于上一层最少有j-1匹马,故循环范围为j-1 to i-1
f[i,j]:=min(f[i,j],f[k,j-1]+(b[i]-b[k])*(c[i]-c[k]));//f[k,j-1]表示k个马在j-1个马厩里的最小不愉快值,再加上这一层的不愉快值后与f[i,j]比较
end;
i表示前i个马,j表示前j个马厩
数组b,c的含义以及f数组的预处理需要自已想(就是把f[i,1]都求出来)
var n,m,k,i,j:longint; a,b,c:array[0..500]of longint; f:array[1..500,1..500]of longint; function min(a,b:longint):longint; begin if a<b then exit(a) else exit(b); end; begin readln(n,m); for i:=1 to n do begin readln(a[i]); if a[i]=1 then begin b[i]:=b[i-1]+1; c[i]:=c[i-1]; end else begin b[i]:=b[i-1]; c[i]:=c[i-1]+1; end; end; for i:=1 to n do f[i,1]:=b[i]*c[i]; for i:=1 to n do for j:=2 to i do begin f[i,j]:=maxint; for k:=j-1 to i-1 do f[i,j]:=min(f[i,j],f[k,j-1]+(b[i]-b[k])*(c[i]-c[k])); end; write(f[n,m]); end.