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.

 

posted on 2014-01-07 16:15  BLADEVIL  阅读(305)  评论(0编辑  收藏  举报