• 【BZOJ4300】绝世好题(动态规划)


    【BZOJ4300】绝世好题(动态规划)

    题面

    BZOJ

    Description

    给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len)。

    Input

    输入文件共2行。
    第一行包括一个整数n。
    第二行包括n个整数,第i个整数表示ai。

    Output

    输出文件共一行。
    包括一个整数,表示子序列bi的最长长度。

    Sample Input

    3

    1 2 3

    Sample Output

    2

    HINT

    (n<=100000,ai<=2*10^9)

    题解

    考虑一个(O(n^2))(dp)
    (f[i]=max(f[j]+1),b[i] and b[j]≠0)
    仔细想想,没必要访问所有的(j)
    只需要访问对于每一个二进制位,上一次出现过的(j)就可以啦
    复杂度(O(nlogn))

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 111111
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int n,a[MAX],f[MAX],ans;
    int lst[65];
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	for(int i=1;i<=n;++i)f[i]=1;
    	for(int i=1;i<=n;++i)
    		for(int j=0;j<31;++j)
    			if(a[i]&(1<<j))f[i]=max(f[i],f[lst[j]]+1),lst[j]=i;
    	for(int i=1;i<=n;++i)ans=max(ans,f[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    【CF833E】Caramel Clouds
    【LG2183】[国家集训队]礼物
    (ex)Lucas总结
    【CF527C】Glass Carving
    【CF833D】Red-Black Cobweb
    【LG4631】[APIO2018]Circle selection 选圆圈
    volatile梳理
    ThreadLocal梳理
    java线程基础梳理
    TCP/IP
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8585626.html
Copyright © 2020-2023  润新知