引子:
那天…我们和初二的同学们一起做了题。
T1 我认为是有必要写一些题解来加深一点印象。
因为自己在做这道题的时候,也是有点懵。
思路(1):
dp(最长上升子序列):
用这个方法呢,是没有问题的,时间复杂度是(N*logn)。因为题目的要求是:
求ai的子序列bi的最长长度。
所以就是可以用 最 长 上 升 子 序 列 。 \color{#FF3030}{最长上升子序列。} 最长上升子序列。
即状态转移方程
f[i]=max{
f[j]+1}且j<i且b[i]&b[j]!=0
但是!注意!
这道题因为你想要AC的话必须要用位运算!
为什么?!那就看下面
思路(2):
二进制优化 (我也不知道到底应该叫什么。):
因为答案只能是由两个在二进制表示下至少有一位同是1的a序列里的数&得到的,最后求子序列的个数f[i]存的是对于a序列中当前遍历到的数中有几个在二进制表示下第i位为1,因为求的是子序列的个数而非方案,所以发现当前的数可以与之前的数&之后得到1满足题目要求,答案就只+1令dp[i]表示数列到目前为止最后一项第i位为1的最大子序列长度,每读入一个数时就
大力转移。一个数可以被它所有的二进制位的dp值转移,然后把它转移到它的所有二进制位的dp值上。
有的同学要问了,怎样求某个数二进制的第i位咧?这时候位运算就闪亮登场了。x&(1<<i)即可求出。
我们来举个栗子:
1 2 3.
转为二进制为:01 10 11
0.f[0]=0 f[1]=0;
1.f[0]=1 f[1]=0;
2.f[0]=1 f[1]=1