bzoj 2064 DP

这道题可以抽象成两个数列,将一个数列变换为另一个

数列的代价最小

首先我们可以处理出所有的状态代表,对于每个状态

用二进制来表示,代表的是两个数列中的每一项选还是不选

那么答案最多为n1+n2-2,也就是先将第一个数列合成一个数

然后再依次拆成第二个数列,那么假设第一个数列选一些,第二个数

列选一些,这个子问题合法(就是第一个数列的选出的和与第二

个的相等),那么我们就没有必要将这个子问题再与大问题合并,也

就是答案减少了2,这样DP就行了

/**************************************************************

    Problem: 2064

    User: BLADEVIL

    Language: Pascal

    Result: Accepted

    Time:1652 ms

    Memory:8416 kb

****************************************************************/

 

//By BLADEVIL

var

    n1, n2, size                    :longint;

    i, j, k                         :longint;

    sum, w                          :array[0..1048576]of longint;

     

procedure init;

begin

    read(n1);

    for i:=1 to n1 do read(sum[1<<i>>1]);

    read(n2);

    for i:=n1+1 to n1+n2 do

    begin

        read(sum[1<<i>>1]);

        sum[1<<i>>1]:=-sum[1<<i>>1];

    end;

    n1:=n1+n2;

    size:=1<<n1-1;

end;

 

procedure calc(x:longint);

begin

    j:=x and (-x);

    sum[x]:=sum[j]+sum[x-j];

    for j:=1 to n1 do

        if x and (1<<j>>1)>0 then

        begin

            k:=x-1<<j>>1;

            if w[k]>w[x] then w[x]:=w[k];

        end;

    if sum[x]=0 then inc(w[x]);

end;

 

begin

    init;

    for i:=1 to size do calc(i);

    writeln(n1-2*w[size]);

end.

 

你可能感兴趣的:(ZOJ)