当前位置: 首页 > 工具软件 > Maniac > 使用案例 >

[SGU]132. Another Chocolate Maniac

秦博达
2023-12-01

Analysis

    还是一道状态压缩题目,与SGU131不同的是,一个要填满,一个不用,这样一来此题中上一行的状态将会影响到当前行,故应在状态表示时记录两行。设f[i,opt1,opt2]是当前为第i行,上一行状态为opt1,当前行状态为opt2时的方案总数,用与前一题相似的方法推到下一个状态。

Accepted Code

var
    f:array[0..1,0..200,0..200] of int64;
    a:array[1..100] of longint;
    i,j,l,m,n,ans,maxopt:longint;
    s:string;

function min(i,j:longint):longint;
begin
    if i<j then
        min:=i
    else
        min:=j;
end;

procedure dfs(k,opt1,opt2,opt3,cnt:longint);
begin
    if (k>0) and (opt1 and (1 shl (k-1))=0) and (opt2 and (1 shl (k-1))=0) then
        exit;
    if (k>1) and (opt2 and (1 shl (k-1))=0) and (opt2 and (1 shl (k-2))=0) then
        exit;
    if k=n then
    begin
        f[i and 1,opt2,opt3]:=min(f[i and 1,opt2,opt3],f[1-i and 1,j,l]+cnt);
        exit;
    end;
    dfs(k+1,opt1,opt2,opt3,cnt);
    if (opt3 and (1 shl k)=0) and (opt2 and (1 shl k)=0) then
        dfs(k+1,opt1,opt2 or (1 shl k),opt3 or (1 shl k),cnt+1);
    if (k<n-1) and (opt2 and (1 shl (k+1))=0) and (opt2 and (1 shl k)=0) then
        dfs(k+2,opt1,opt2 or (1 shl k) or (1 shl (k+1)),opt3,cnt+1);
end;

begin
    readln(m,n);
    for i:=1 to m do
    begin
        readln(s);
        a[i]:=0;
        for j:=1 to n do
            if s[j]='*' then
                a[i]:=a[i] or (1 shl (j-1));
    end;
    maxopt:=1 shl n-1;
    for j:=0 to maxopt do
        for l:=0 to maxopt do
            f[0,j,l]:=maxlongint div 2;
    f[0,maxopt,a[1]]:=0;
    for i:=1 to m do
    begin
        for j:=0 to maxopt do
            for l:=0 to maxopt do
                f[i and 1,j,l]:=maxlongint div 2;
        for j:=0 to maxopt do
            for l:=0 to maxopt do
                if f[1-i and 1,j,l]<>maxlongint div 2 then
                    dfs(0,j,l,a[i+1],0);
    end;
    ans:=maxlongint div 2;
    for i:=0 to maxopt do
        ans:=min(ans,f[m and 1,i,0]);
    writeln(ans);
end.



 类似资料:

相关阅读

相关文章

相关问答