BZOJ4300: 绝世好题

题目链接

走这里

题目分析

确实是绝世好题
喵?为什么大家都觉得是个裸DP……
_(:з」∠)_可能是我tcl,有了\(O(n^2)\)的解之后一直没搞出优化到\(log\)级别的办法,最后还是看了博客

先说一下第一眼能得到的方程
\(dp[i] = max(dp[j] + (a[i] \& a[j] != 0) (1 <= j <= i)\)
但是发现这个玩意是\(O(n^2)\)的,考虑如何优化
考虑什么时候两个数按位与的结果不是\(0\),显然只要有一位上它们俩都是\(1\)就可以了,所以我们另外记录一个数组\(mx[j]\),表示处理到现在所有二进制下第\(j\)位是1的\(a[k](1 <= k <= i)\)对应的\(dp[i]\)的最大值
那么重新得到一个状态转移方程:
$dp[i] = max(mx[j]) + 1 (a[i]二进制表示下第j位是1) $
因为\(a_i <= 2 * 10 ^ 9\),所以我们的\(j\)只需要枚举到31即可
时间复杂度\(O(nloga)\)

代码

#include <bits/stdc++.h>
#define N (200000 + 10)
using namespace std;
inline int read() {
    int cnt = 0, f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + c - '0'; c = getchar();}
    return cnt * f;
}
int n, a[N], dp[N], mx[100];
int ans = -1;
int main() {
    n = read();
    for (register int i = 1; i <= n; i++) a[i] = read();
    dp[1] = 1;
    for (register int i = 1; i <= n; i++){
        for (register int j = 0; j <= 31; j++) 
            if (a[i] & (1 << j)) dp[i] = max(dp[i], mx[j] + 1);
        for (register int j = 0; j <= 31; j++)
            if (a[i] & (1 << j)) mx[j] = max(dp[i], mx[j]);
        ans = max (ans, dp[i]);
    }
    printf("%d", ans);
    return 0;
}

转载于:https://www.cnblogs.com/kma093/p/11301900.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值