[bzoj]1806: [Ioi2007]Miners 矿工配餐
【。。】虽然A了但一点感情都没有。。毕竟看了题解
【算法】动态规划
【思路】
f[now,i,j,k,l]表示前now辆车,第一个煤矿之前两种食物为i,j,第二个煤矿之前两种食物为k,l的最大收益
calc(i,j,k)表示之前三种食物为i,j,k时的产煤量
【方程】
f[now,i,j,k,l]=max(f[now,i,j,k,l],f[now-1,j,x,k,l]+calc(i,j,x),f[now-1,i,j,l,x]+calc(k,l,x))
x 表示新来的食物
【notice】内存会超所以要滚动
【Code】//求大神轻喷
var
i,j,k,l,n,m,tmp,now,x,y,z,ans:longint;
s:ansistring;c:char;
f:array[0..1,0..3,0..3,0..3,0..3]of longint;
function max(i,j:longint):longint;
begin
if i>j then exit(i);exit(j);
end;
function turn(c:char):longint;
begin
if c='M' then exit(1);
if c='F' then exit(2);
if c='B' then exit(3);
end;
function calc(i,j,k:longint):longint;
var tmp:longint;
begin
tmp:=1;
if (i<>0)and(i<>j)and(i<>k)then inc(tmp);
if (j<>0)and(j<>k)then inc(tmp);
exit(tmp);
end;
procedure dp(c:char;now:longint);
var i,j,k,l,tmp,x:longint;
begin
x:=turn(c);
for i:=0 to 3 do
for j:=0 to 3 do
for k:=0 to 3 do
for l:=0 to 3 do
if f[1-now,i,j,k,l]<>-1 then begin
tmp:=calc(i,j,x);
f[now,j,x,k,l]:=max(f[now,j,x,k,l],f[1-now,i,j,k,l]+tmp);
tmp:=calc(k,l,x);
f[now,i,j,l,x]:=max(f[now,i,j,l,x],f[1-now,i,j,k,l]+tmp);
end;
end;
begin
readln(n);
readln(s);
fillchar(f,sizeof(f),-1);
f[0,0,0,0,0]:=0;
x:=1;ans:=0;
for i:=1 to n do begin
dp(s[i],x);
x:=1-x;
end;
x:=1-x;
for i:=0 to 3 do
for j:=0 to 3 do
for k:=0 to 3 do
for l:=0 to 3 do
ans:=max(ans,f[x,i,j,k,l]);
writeln(ans);
end.