把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P4310 绝世好题

题面传送门
这道\(dp\)还是比较水的
首先考虑设\(f_i\)为以\(a_i\)结尾的最长长度,则向前循环枚举找到适合的转移就可以了,时间复杂度\(O(n^2)\),估计\(80\)
正解也不是很难想,因为这是位运算,所以我们要找到位运算的性质,\(\&\)的性质就是两个数至少有一个相同位置同为\(1\),那么只要枚举位置转移就好了,设\(s_i\)为结尾的数中二进制第\(i\)位为\(1\)的最大值,那么\(f_i\)只要从\(i\)二进制位上为\(1\)的地方转移就可以了。
代码实现:

#include<cstdio>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n,m,a,f,s[39],tot,pus,ans;
int main(){
	register int i;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d",&a);
		pus=a;
		tot=f=0;
		while(pus){
			if(pus&1) f=max(s[tot],f);
			tot++;
			pus>>=1;
		}
		f++;
		pus=a;
		tot=0;
		while(pus){
			if(pus&1) s[tot]=max(s[tot],f);
			tot++;
			pus>>=1;
		}
		ans=max(ans,f);
	}
	printf("%d\n",ans);
}
posted @ 2020-03-20 19:53  275307894a  阅读(28)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end