马厩分配问题

【问题描述】
每天,农夫Ion都会去放马。让马儿去跑跑和玩耍。完了之后,Ion还有把马儿关回马厩。为了做好这件事,Ion让马排成一行跟着他入马厩。因为马儿已经很累了,Ion不想让马儿再走更多的路,因此他想出了一个就近入厩的办法:让前P1匹马进入第一个马厩,然后的p2匹马进入第二个马厩,如此类推。
而且,他不想让任何一个马厩(共K个)留空,还有所有的马都进入马厩。
已知Ion只有黑色和白色两种颜色的马,然而并不是所有的马都能相处融洽。假如有i匹黑马和j匹白马同在一个马厩,那么它们之间的不愉快系数为i*j.马厩总的不愉快系数等于K个马厩的不愉快系数之和。(不愉快可能表现在马儿互相打架,引起伤亡,Ion损失就大了)。
请你帮忙设计一种方案,把N匹马顺序放入k个马厩中,令到马厩总的不愉快系数最小。
【输入】
第一行为2个数n,k表示有n匹马,k个马厩。
后面n行每行一个整数表示每匹马的颜色,1表示黑色,0表示白色。
【输出】
一个整数表示马厩总的最小不愉快系数。
样例输入 Sample Input
 6 3
1
1
0
1
0
1
样例输出 Sample Output
 2
说明:前2匹马入第一个马厩,中间3匹入第二个马厩,最后一匹入第三个
30%的数据 n<=30

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.


你可能感兴趣的:(dp,动态规划,pascal,noip)