HYSBZ(BZOJ) 4300 绝世好题(位运算,递推)
HYSBZ(BZOJ) 4300 绝世好题(位运算,递推)
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
Http
HYSBZ:http://www.lydsy.com/JudgeOnline/problem.php?id=4300
Source
递推,位运算
解决思路
初看这道题目,觉得有点像最长不下降子序列,但是又有些不同。
在这里我们要巧妙地运用题目中给出的位运算的条件。
首先我们看题目中对b序列的x要求:
\]
这也就是说,如果我们把每一个数都转成2进制,那么要求两个数至少有相同的一位都是1。
什么意思,还是画图来分析:

现在我们有这两个数都转成二进制存在上面,如果他们有相同的一位都是1,即可以连接(如下图)

这样的两个数就可以连接。
而若是像下图这样,就不可以连接:

跟据上面我们的分析,我们设一个数组Solve,Solve第i位表示如果接在二进制的第i位上现在能接的最长长度。
那么如何计算Solve呢?
对于每一个数(假设是x),我们从低位到高位依次扫描x中是1的位置,取出对应的Solve数组中的最大值,然后把Solve中的这些值全部更新为这个最大值+1。
直接这么说可能会有些头大,我们还是借助图来说明一下。
假设我们现在有这样一个例子,左边是Solve数组,右边是x转成二进制后的样子

现在我们框出对应X的位上为1的Solve数组的数,并选出最大值(红框框起来的就是选出的数,黄框是最大值):

将所有框中(zhong4声)的Solve的值都更新为最大值+1

这样处理每一个数,最后Solve数组中最大的就是结果了。
为什么这样是对的呢?
参考一下我们最长不下降子序列的做法,我们是设F[i]表示以i结尾的最长不下降子序列的长度,那么在这里,Solve[i]表示的是二进制以第i位为真结尾的最长满足题意的子序列。所以,我们这样做是对的。
另外可能产生疑问的一个地方就是我们为什么更新答案的时候是所有是1的那一位的答案都要更新成最大值+1呢?
因为根据我们对Solve的定义,既然这一位是1并且通过另外的方式连过来的长度更长,尽管并不是从这一位连过去的,但从定义出发,这里也是可以的。
这个地方不是很好理解,如果还有疑问,可以在留言区留言,博主会尽量回复。
PS:话说这真是一道绝世好题
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN=100001;
const int inf=2147483647;
int n;
int A[maxN];
int Solve[40]={0};
int main()
{
cin>>n;
for (int i=1;i<=n;i++)
cin>>A[i];
int Ans=0;
for (int i=1;i<=n;i++)
{
int now_ans=1;
for (int j=0,sum=1;j<=40;j++,sum=sum<<1)//取出最大值
if (sum&A[i])
now_ans=max(now_ans,Solve[j]+1);
for (int j=0,sum=1;j<=40;j++,sum=sum<<1)//把所有在x上这一位是1的都更新成当前最大值+1
if (sum&A[i])
Solve[j]=max(Solve[j],now_ans);
Ans=max(now_ans,Ans);//更新最后要输出的最大值
}
cout<<Ans<<endl;
return 0;
}
HYSBZ(BZOJ) 4300 绝世好题(位运算,递推)的更多相关文章
- BZOJ 4300: 绝世好题 动态规划
4300: 绝世好题 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4300 Description 给定一个长度为n的数列ai,求ai的 ...
- 【递推】BZOJ 4300:绝世好题
4300: 绝世好题 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 564 Solved: 289[Submit][Status][Discuss] ...
- bzoj 4300: 绝世好题 dp
4300: 绝世好题 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php ...
- bzoj 4300: 绝世好题
4300: 绝世好题 Time Limit: 1 Sec Memory Limit: 128 MB Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi& ...
- BZOJ 4300 绝世好题(位运算)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4300 [题目大意] 给出一个序列a,求一个子序列b,使得&和不为0 [题解] ...
- bzoj 4300 绝世好题——DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4300 考虑 dp[ i ] 能从哪些 j 转移过来,就是那些 a[ j ] & a[ ...
- bzoj 4300 绝世好题 —— 思路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4300 记录一下 mx[j] 表示以第 j 位上是1的元素结尾的子序列长度最大值,转移即可. ...
- bzoj 4300: 绝世好题【dp】
设f[i][j]表示数列到i为止最后一项第j位为1的最大子序列长度,每次从i-1中1<<j&a[i]!=0的位+1转移来 然后i维是不需要的,答案直接在dp过程中去max即可 #i ...
- BZOJ 4300: 绝世好题 二进制
对于每一个数字拆位,然后维护一个大小为 30 左右的桶即可. code: #include <bits/stdc++.h> #define N 100006 #define setIO(s ...
随机推荐
- XSS构造技巧
利用字符编码: 百度曾经出过一个XSS漏洞,在一个<script>标签中输出一个变量,其中转义了双引号: var redirectUrl="\";alert(/XSS/ ...
- dvwa——命令注入&文件包含
命令注入 commond_injection 源码.分析.payload: low: <?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input ...
- trustbox文件破解
常见的破解方式,是要还原内容的二进制文件,删除加密壳部分的对应二进制数值,然后把剩下的内容保存下来,就实现了破解的任务. 淘宝破解链接:https://item.taobao.com/item.ht ...
- css方法div固定在网页底部
css .bottom{width:%;height:40px;background:#ededed;;}/*重点后两句*/ body <div class="bottom" ...
- WPF四则运算《《《《《策略模式
设计思路: 因为之前没有用过WPF,听说和window窗体语法类似,就想着仿照之前的Window窗体做的,首先用三个textbox存储数据,添加一个comboBox,利用索引选择运 ...
- C#编程之神奇程序找数
C#编程之神奇程序找数 问题1:这个程序要找的是符合什么条件的数? 问题2:这样的数存在么?符合这一条件的最小的数是什么? 问题3:在电脑上运行这一程序,你估计多长时间才能输出第一个结果?时间精确到分 ...
- 用户数以及psp
小组名称:好好学习 小组成员:林莉 王东涵 胡丽娜 宫丽君 项目名称: 记账本 alpha发布48小时以后用户数如何,是否达到预期目标,为什么,是否需要改进,如何改进(或理性估算). 首先我 ...
- HDU 1231 最大子序列
http://acm.hdu.edu.cn/showproblem.php?pid=1231 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连 ...
- XLSReadWriteII5使用示例
之前一直是使用XLSReadWriteII4,今天更新到XLSReadWriteII5,测试了一下,发现一些操作变化比较大,现将XLSReadWriteII5的使用示例写一下,以下是代码和生成的exc ...
- macOS how to install python3
macOS how to install python3 macOS & Python 3.7.2 https://www.python.org/downloads/mac-osx/ http ...