P4310 绝世好题 数位DP

题面:

对于一个长度为\(n\)的序列\(a_i\),找出一个子序列\(b_i\)(PS:子序列可以不连续)满足\(b_i\) & \(b_{i-1} \ne 0\) ,求\(b_i\)长度最大值

范围&性质:\(1\le n\le 10^5,1\le a_i \le 10^9\)

分析:

暴力做法 \(\omicron (n^2)\) 的枚举

正解:由于n很大,所以我们对于每一个数按位拆分,进行DP,记\(f[i]\)表示枚举到当前这个数时,前面第\(i\)为1的数的子序列最大长度,记\(tmp\)为当前位的答案,转移式如下:

\[tmp =max(f[i]+1,tmp) \]

\[f[i]=max(f[i]+1,tmp) \]

代码:

#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
	
	const int maxn = 1e5+5;
	int f[50];
	int n,ans=0;
	
	void work()
	{
		scanf("%d",&n);
		for(int i=1,x;i<=n;i++)
		{
			scanf("%d",&x);
			int mx=1;
			for(int i=0;i<=32;i++)
			{
				if(x&(1<<i)) mx=max(f[i]+1,mx);
			}
			for(int i=0;i<=32;i++)
			{
				if(x&(1<<i)) f[i]=max(mx,f[i]+1);
			}
			ans=max(ans,mx); 
		}
		printf("%d",ans);
	}
	
}

int main()
{
	zzc::work();
	return 0;
}
原文地址:https://www.cnblogs.com/youth518/p/13650268.html