bzoj1296: [SCOI2009]粉刷匠

来源:互联网 发布:合并分区软件 编辑:程序博客网 时间:2024/05/17 02:27

传送门
对于每一行,跑一个dp,f[i][j]表示前i个字符,刷j次的最优解。
然后在外层再跑dp,g[i][j]表示前i行刷j次最多刷对几个。
还是很简单的。

uses math;var  f:array [0..55,0..55,0..55] of longint;  b:array [0..55,0..55] of longint;  g:array [0..55,0..2505] of longint;  s:string;  n,m,t,p,i,j,k,l:longint;  a:array [0..55] of longint;begin  readln(n,m,t);  for p:=1 to n do begin    readln(s);    for j:=1 to m do if (s[j]='1') then a[j]:=a[j-1]+1 else a[j]:=a[j-1];    fillchar(f,sizeof(f),0);    for j:=1 to m do      for k:=j to m do        f[1,j,k]:=max(max(f[i,j+1,k],f[i,j,k-1]),max(a[k]-a[j-1],k-j+1-(a[k]-a[j-1])));    for i:=2 to m do      for j:=1 to m do        for k:=j to m do          for l:=j to k-1 do            f[i,j,k]:=max(max(f[i,j,k],f[i,j+1,k]),max(f[i,j,k-1],max(f[i-1,j,l]+f[1,l+1,k],f[1,j,l]+f[i-1,l+1,k])));    for i:=1 to m do b[p,i]:=f[i,1,m];  end;  for i:=1 to n do    for j:=0 to t do      for k:=0 to m do        if (j+k<=t) then g[i,j+k]:=max(g[i,j+k],g[i-1,j]+b[i,k]);  write(g[n,t]);end.
0 0
原创粉丝点击