【递推】BZOJ 4300:绝世好题

4300: 绝世好题

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 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的最长长度。

Sample Input

3
1 2 3

Sample Output

2

HINT

对于100%的数据,1<=n<=100000,ai<=10^9。



  刚考完联赛回家搞了一个星期常规=- =

  然后老师叫我们还是要保持一下手感的是吧

  然后随便找了一道水题。。

  貌似是单调DP?

  发现不行

  然后想了一下按位单调DP

  感觉好像可以但不是最优解。。

  看了一下status

  发现最短的代码400b左右

  貌似不是单调DP?

  然后查了一下。。

  f[j]代表第j位的最优值

  之后每次更新一个数每一位的最优值为所有位的f值+1即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5
 6 #define maxn 100001
 7
 8 using namespace std;
 9
10 int a[maxn],f[maxn];
11
12 inline int in()
13 {
14     int x=0;char ch=getchar();
15     while(ch<‘0‘||ch>‘9‘)ch=getchar();
16     while(ch<=‘9‘&&ch>=‘0‘)x=x*10+ch-‘0‘,ch=getchar();
17     return x;
18 }
19
20 int main()
21 {
22     int n;
23     n=in();
24     for(int i=1;i<=n;i++)a[i]=in();
25     for(int i=1;i<=n;i++)
26     {
27         int cal=0;
28         for(int j=0;j<=30;j++)if(a[i] & (1<<j))cal=max(cal,f[j]+1);
29         for(int j=0;j<=30;j++)if(a[i] & (1<<j))f[j]=cal;
30     }
31     int ans=0;
32     for(int j=0;j<=30;j++)ans=max(ans,f[j]);
33     printf("%d",ans);
34     return 0;
35 }

时间: 2024-11-20 04:31:51

【递推】BZOJ 4300:绝世好题的相关文章

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: 绝世好题( 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 绝世好题(位运算)

[题目链接] 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

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<alg

(水 递推) bzoj 1088

1088: [SCOI2005]扫雷Mine Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1820  Solved: 1084[Submit][Status][Discuss] Description 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字表示和它8连通的格子里面雷的数目.现在棋盘是n×

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的