bzoj 4300 绝世好题——DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4300

考虑 dp[ i ] 能从哪些 j 转移过来,就是那些 a[ j ] & a[ i ] != 0 的,也就是有至少1位公共的1;所以在30位上记录这一位是1的那些 a[ ] 中的 dp[ ] 最大值,就能转移了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5,M=35;
int n,a[N],bin[M],c[M],lm,ans;
int rdn()
{
  int ret=0;bool fx=1;char ch=getchar();
  while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)fx=0;ch=getchar();}
  while(ch>=‘0‘&&ch<=‘9‘) ret=(ret<<3)+(ret<<1)+ch-‘0‘,ch=getchar();
  return fx?ret:-ret;
}
int main()
{
  int tp=0;
  n=rdn();for(int i=1;i<=n;i++)a[i]=rdn(),tp=max(tp,a[i]);
  while(tp)lm++,tp>>=1; lm--;
  bin[0]=1;for(int i=1;i<=lm;i++)bin[i]=bin[i-1]<<1;
  for(int i=1;i<=n;i++)
    {
      int d=0;
      for(int j=0;j<=lm&&bin[j]<=a[i];j++)
    if(a[i]&bin[j])d=max(d,c[j]);
      d++;
      for(int j=0;j<=lm&&bin[j]<=a[i];j++)
    if(a[i]&bin[j])c[j]=max(c[j],d);
    }
  for(int j=0;j<=lm;j++)ans=max(ans,c[j]);
  printf("%d\n",ans);
  return 0;
}

原文地址:https://www.cnblogs.com/Narh/p/9887220.html

时间: 2024-08-10 04:07:56

bzoj 4300 绝世好题——DP的相关文章

BZOJ 4300: 绝世好题( dp )

dp(i)表示二进制的第i位为1时的最大值, 然后从左到右dp ------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define b(i) (1 << (i)) const int maxn = 100009; c

【递推】BZOJ 4300:绝世好题

4300: 绝世好题 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 564  Solved: 289[Submit][Status][Discuss] Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len). Input 输入文件共2行. 第一行包括一个整数n. 第二行包括n个整数,第i个整数表示ai. Output 输出文件共一行. 包括一个整数,表示子序列bi的

bzoj 4300: 绝世好题

4300: 绝世好题 Time Limit: 1 Sec  Memory Limit: 128 MB 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

BZOJ 4300 绝世好题(位运算)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4300 [题目大意] 给出一个序列a,求一个子序列b,使得&和不为0 [题解] 记录某个位置上为1的&序列长度的最长值,对于每个加入的数字, 更新每个数组. __builtin_ctz(x)函数用于求出x的二进制位数. [代码] #include <cstdio> #include <algorithm> int x,ans,res,n,a[40]; us

BZOJ 4300: 绝世好题 二进制

这是道动规的题,还好.昨晚在睡前想了一下,结合了之前解题的经验,首先有关二进制运算的很多都是独立的,所以我们可以把这道题弄成这样,设 a[i] 为 如果 j 的二进制第 i 位为一所能取得的最大长度,然后在 j 的所有二进制为 1 的数中取 a[i] 最大的,并更新其他的二进制位.就这样了,加油啊!还挺顺利的. 这个跑了48毫秒 1 #include<cstdio> 2 #include<iostream> 3 #define rep(i,j,k) for(int i = j; i

bzoj 4300 绝世好题 —— 思路

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4300 记录一下 mx[j] 表示以第 j 位上是1的元素结尾的子序列长度最大值,转移即可. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int const xn=1e5+5,xm=32; int

4300: 绝世好题

Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 3267  Solved: 1761[Submit][Status][Discuss] Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len). Input 输入文件共2行. 第一行包括一个整数n. 第二行包括n个整数,第i个整数表示ai. Output 输出文件共一行. 包括一个整数,表示子序列bi的最长长度. Sam

【BZOJ 4300】绝世好题

4300: 绝世好题 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 540  Solved: 278[Submit][Status][Discuss] Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len). Input 输入文件共2行. 第一行包括一个整数n. 第二行包括n个整数,第i个整数表示ai. Output 输出文件共一行. 包括一个整数,表示子序列bi的

bzoj4300 绝世好题(位运算+DP)

为什么要写这道题呢?因为它是"绝世好题". 题意:给定n个数,在其中找出一段子序列b,使得b[i]&b[i-1]!=0,求出满足条件的最长子序列长度. 输入:第一行:一个整数n,表示数列的个数. 第二行:n个整数,表示数列a. 输出:一行,一个整数,表示最长的子序列长度. 输入样例: 3 1 2 3 输出样例: 2 解析:若b[i]&b[i-1]!=0,即b[i]与b[i-1]在二进制下有一位相同且都为1.那么设dp[i]表示前i个数所能达到的最长子序列长度,那么在转移