【NOIP2018复习】B(区间DP)

1275.

时间限制:1000MS内存限制:256000KB

题目描述

由于wangjp小学生数学题都不会做,给大家在考场上带来了很大的麻烦,他决心好好学习数学
本次他挑选了位运算专题进行研究 他发明了一种叫做“wangjp运算”的运算符:a$b =( (a&b) + (a|b) )>>1他为了练习,写了n个数在黑板上(记为a[i]) 并对任意相邻两个数进行“wangjp运算”,把两数擦去,把结果留下 这样操作n-1次之后就只剩了1个数,
这个数可能是什么?
将答案从小到大顺序输出
 

输入

输出

输入样例复制

4
1 4 3 2

输出样例复制

1 2

说明

Data Constraint 30% n<=10 0<=a[i]<=7 70% n<=150 0<=a[i]<=3 100% n<=150 0<=a[i]<=7

 题解:观察可得该运算是求平均数,所以结果的集合为【0,7】,区间DP
           f[i,j,0..7]表示[i,j]是否可以变为[0..7]中的数
           枚举一个长度起点和断点,f[i,j,p]=f[i,k,p1] and f[k+1,j,p2]  (p=(p1+p2)div 2)
           错误做法:不能一个点一个点扩展状态,因为有可能两个区间结合在一起
           

const

  maxn=200;

var

  f:array[0..maxn,0..maxn,0..7]of longint;

  a:array[1..maxn]of longint;

  n,len,i,kk,k,j,p1,p2:longint;

procedure init;

var

  i:longint;

begin

  readln(n);

  for i:=1 to n do

  begin

    read(a[i]);

    f[i,i,a[i]]:=1;

  end;

end;

function max(a,b:longint):longint;

begin

  if a>b then exit(a) else exit(b);

end;

function check(x,y:longint):longint;

begin

  check:=((x and y)+(x or y))shr 1;

end;

procedure gogo(i,j:longint);

var

  k,kk,p1,p2,k1,k2:longint;

begin

  for k:=i to j-1 do

  begin

    for k1:=0 to 7 do

     if (f[i,k,k1]=1) then

      for k2:=0 to 7 do

      begin

        kk:=(k1+k2)shr 1;

        f[i,j,kk]:=max(f[i,k,k1] and f[k+1,j,k2],f[i,j,kk]);

      end;

  end;

 {  for k:=0 to 7 do

      begin

        for kk:=0 to 7 do

        begin

          p1:=check(kk,a[i]);

          p2:=check(kk,a[j]);

          if p1=k then f[i,j,k]:=max(f[i+1,j,kk],f[i,j,k]);

          if p2=k then f[i,j,k]:=max(f[i,j-1,kk],f[i,j,k]);

        end;

      end;}

end;

begin

  init;

  for len:=1 to n do

    for i:=1 to n-len do

    begin

      j:=len+i;

      gogo(i,j);

    end;

  for i:=0 to 7 do

    if f[1,n,i]=1 then write(i,' ');

end.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值