当前位置: 首页 > news >正文

【状态设计优化DP】P4310 绝世好题

不愧是绝世好题

和abc那道E一样,也是重新定义状态来优化转移复杂度的DP

(56条消息) Atcoder Beginner Contest E - Work or Rest_lamentropetion的博客-CSDN博客

这种其实就是通过转移方式的特殊性来设计状态,从而降低复杂度

其实我感觉降低复杂度优化就是因为某个地方比较特殊,然后根据这个特殊性来优化

还有一点就是关于子序列的DP一般都以a[i]结尾来定义

这题是我做过的唯一线性DP设计状态的时候没加阶段的DP了,所以有点哈希内味

这种DP妙妙题我还没怎么写过,只会笨笨的那种DP,感觉得多写这种DP了

P4310 绝世好题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题意:

思路:

首先就是每个人都会的暴力DP,像LIS那样,这样是n^2的,显然T飞了

我们来重新设计状态

考虑它的转移方式:当且仅当某一位两个数该位都是1时转移,因此我们定义dp[i]为最后一个数的第i位为1的最长长度

在加入某个数之前,我们遍历位统计出此时dp[i]的最大值

然后在加入这个数之后来转移

加入这个数之后,所有位都变成了那个统计出来的最大值+1,这样就转移好了

Code:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mxn=1e5+10;
int n;
int a[mxn],dp[32];
void solve(){
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++){
        int mx=-1;
        for(int j=30;j>=0;j--){
            if((a[i]>>j)&1) mx=max(mx,dp[j]);
        }
        for(int j=30;j>=0;j--){
            if((a[i]>>j)&1) dp[j]=max(dp[j],mx+1);
        }
    }
    int mx=-1;
    for(int j=30;j>=0;j--) mx=max(mx,dp[j]);
    cout<<mx<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;//cin>>__;
    while(__--)solve();return 0;
}

总结:

怎么去定义状态:

考虑转移方式,根据转移方式的特殊性来定义状态

这道题在设计状态时没有考虑阶段,所以有点哈希的感觉,我愿称之为哈希DP(bushi

还有一点就是关于子序列的DP一般都以a[i]结尾来定义

相关文章:

  • 宝塔window怎么做网站/如何创建网站平台
  • 网站评论怎么做的/seo兼职怎么收费
  • 做 网站 技术支持 抓获 互助/黑帽seo技术论坛
  • 三站合一网站建设方案/qq群推广方法
  • 做网站不如做公众号/网站模板免费
  • 做快三网站/办公软件速成培训班
  • UOS服务器操作系统KVM虚拟机迁移
  • 论文解读 - 城市自动驾驶车辆运动规划与控制技术综述 (第3部分)
  • 超实用的微信公众号内容运营方案分享
  • CSS设置元素字体、降级使用字体、引入外部字体
  • Himall商城ExpressDaDaHelper 商家投诉达达
  • DataGear 4.4.0 发布,数据可视化分析平台
  • 剑指 Offer 36. 二叉搜索树与双向链表
  • 软件测试复习06:基于经验的测试
  • uml图 各连接线的含义
  • 教程: nodejs 做微信公众号开发,回复 xml 消息
  • 【web安全】——HTTP请求头注入
  • javaweb11 JavaBean、MVC架构、Filter过滤器、监听器、设置欢迎页面