POJ1692

var   f:array[0..101,0..101] of longint;
      a,b:array[0..101] of longint;
      dnum,dx,n1,n2,i,j,p,q:longint;


      function max(a,b:longint):longint;
      begin if a>b then exit(a); exit(b); end;

begin
      readln(dnum);
      for dx:=1 to dnum do
      begin
            fillchar(f,sizeof(f),0);
            readln(n1,n2);
            for i:=1 to n1 do read(a[i]); readln;
            for i:=1 to n2 do read(b[i]); readln;
            for i:=1 to n1 do
               for j:=1 to n2 do
               begin
                     f[i,j]:=max(f[i-1,j],f[i,j-1]);
                     if a[i]=b[j] then continue;
                     for p:=i-1 downto 1 do
                        if a[p]=b[j] then break;
                     if a[p]=b[j] then
                     begin
                           for q:=j-1 downto 1 do
                              if b[q]=a[i] then break;
                           if b[q]=a[i] then
                             f[i,j]:=max(f[i,j],f[p-1,q-1]+2);
                     end;
               end;
            writeln(f[n1,n2]);
      end;
end.


 

题意:给出两行数,求上下匹配的最多组数是多少.
匹配规则
1.匹配对的数字必须相同
2.每个匹配必须有且只能有一个匹配与之相交叉,且相交叉的两组匹配数字必须不同
3.一个数最多只能匹配一次

分析:DP.f[i,j]表示上面到i,下面到j的匹配对数.

f[i,j]=max(f[i-1,j],f[i,j-1],max{f[p-1,q-1]+2} (a[p]=b[j] & b[q]=a[i])).

code:

转载于:https://www.cnblogs.com/exponent/archive/2011/08/10/2133779.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值