首页 > 其他分享 >谈一类计数DP——DP套DP

谈一类计数DP——DP套DP

时间:2024-11-22 20:55:37浏览次数:1  
标签:lfloor sum times 计数 DP 一类 Check dp choose

谈一类计数dp——dp套dp

一、dp套dp的定义

dp套dp就是一种将dp的值存入另一个dp的状态,而外层另作一个dp去取得记录这种状态的方案数。

二、dp套dp的搜索表征

对于一般的计数dp而言,其搜索形如:

void DFS(int x){
    if(x==n+1)return void(ans+=Check());
    for(int i=1;i<=m;i++){
        ...
        DFS(x+1)
        ...
    }
}

如果这个Check()是一个朴素的对决策的检查,那么转换后是一个朴素计数dp,往往去维护一些 Check() 里面关心的量,但如果 Check() 需要一个 dp 去实现,那么转换后就是一个dp套dp。

三、dp套dp 的实现,内层应该存储什么?

很简单,内层应该存储可以等价实现 Check() 转移的信息。
我们搜索的内容就是我们的决策,那么就应该存储最少的信息与决策相结合是可以进行Check() 函数中的转移。

但如果内层dp不是一个Check()而是另一个计数dp,那么不是传统的dp套dp,即外层状态不能是内层状态的值,而是因该将内层状态与外层状态合并,使得可以通过外层决策转移,见2024.11.22T3 Transformation.

四、例题



首先不难写出一个搜索:

void Deal(){
    for(int i=1;i<=n;i++){
        f[i]=1;
        for(int j=1;j<i;j++)if(mp[j][i]&&(c[i]^c[j]))f[i]^=f[j];
    }
    int res=0;
    for(int i=1;i<=n;i++)res^=f[i];
    ans+=(res==p);
    return;
}
void DFS2(int x,int y){
    if(y==n+1)return DFS2(x+1,x+2);
    if(x==n+1)return Deal();
    mp[x][y]=1;
    DFS2(x,y+1);
    mp[x][y]=0;
    DFS2(x,y+1);
    return;
}
void DFS1(int x){
    if(x==n+1)return DFS2(1,2);
    if(c[x]!=-1)return DFS1(x+1);
    c[x]=0;
    DFS1(x+1);
    c[x]=1;
    DFS1(x+1);
    c[x]=-1;
    return;
}

我们发现这个搜索的Check是以一个dp实现的(即Deal()函数),那么我们考虑用dp套dp优化,首先发现这个Deal()的决策是什么,显然就是我们所搜的mp与c。

我们假设在位置 \(i\) 的时候仅仅决策 \(c_i\) 与 \(\forall j<i,mp[j][i]\),发现 \(f_i\) 的值,仅与 \(f_j=1\land c_j\ne c_i\) 的 \(j\) 有关,并且这些 \(j\) 是无标号的,你可以在这些 \(j\) 中选取偶数个连边使得 \(f_i=1\),或者选取奇数个连边使得 \(f_i=0\),其他的随便连边,不会影响 \(f_i\) 的值所以你可以这样设计外层dp的状态:

设 \(dp_{i,x,y}\) 表示考虑 \(1\sim i\) 的节点,\(\sum_{j<i\land c_j=0}[f_j=1]=x,\sum_{j<i\land c_j=1}[f_j=1]=y\) 时的连边方案数,考虑一次 \(i\to i+1\) 的扩展。

  • 当 \(c_i=0\):

    • 选择奇数条边,那么 \(x\to x+1\),所以:\(dp_{i+1,x+1,y}\leftarrow dp_{i,x,y}\times (\sum_{i=0}^{\lfloor\frac y2\rfloor}{y\choose 2i+1})\times 2^{i-y}\)

    • 选择偶数条边,那么 \(x\) 不变,所以:\(dp_{i+1,x,y}\leftarrow dp_{i,x,y}\times \sum_{i=0}^{\lfloor\frac y2\rfloor}{y\choose 2i}\times 2^{i-y}\)

  • 当 \(c_i=1\):

    • 选择奇数条边,那么 \(y\to y+1\),所以:\(dp_{i+1,x,y+1}\leftarrow dp_{i,x,y}\times \sum_{i=0}^{\lfloor\frac x2\rfloor}{x\choose 2i+1}\times 2^{i-x}\)

    • 选择偶数条边,那么 \(y\) 不变,所以:\(dp_{i+1,x,y}\leftarrow dp_{i,x,y}\times \sum_{i=0}^{\lfloor\frac x2\rfloor}{x\choose 2i}\times 2^{i-x}\)

因为有公式 \(\sum_{i=0}^{\lfloor\frac y2\rfloor}{y\choose 2i+1}=[y>0]2^{y-1},\sum_{i=0}^{\lfloor\frac y2\rfloor}{y\choose 2i}=[y>0]2^{y-1}+[y=0]2\)

所以原转移可以化简为一个不与 \(x,y\) 具体的值有关,但与 \(x,y\) 是否大于 \(0\) 有关。

于是令 \(dp_{i,x',y'}\) 中表示 \(x',y'\) 分别表示 \(x,y\) 是否大于 \(0\),由于最后统计答案还要看 \(x+y\) 的奇偶性,所以再开一维 \(j\) 表示就行了,复杂度 \(\mathcal O(n)\)。

标签:lfloor,sum,times,计数,DP,一类,Check,dp,choose
From: https://www.cnblogs.com/lupengheyyds/p/18563726

相关文章

  • 树形dp模板
    入门题目:最大子树和、女仆咖啡厅桌游吧#include<bits/stdc++.h>usingnamespacestd;intf[16001];intcnt[16001];inta[16001];vector<int>e[16001];intn;intmx=-10000000;voiddfs(intn,intfa){ f[n]=a[n]; for(inti=0;i<e[n].size();i++) { if(e[n][i]!=f......
  • yolov5无人机视频检测与计数系统(创新点和代码)
    标题:基于YOLOv5的无人机视频检测与计数系统摘要:无人机技术的快速发展和广泛应用给社会带来了巨大的便利,但也带来了一系列的安全隐患。为了实现对无人机的有效管理和监控,本文提出了一种基于YOLOv5的无人机视频检测与计数系统。该系统通过使用YOLOv5目标检测算法,能够准确地......
  • TCP和UDP
    TCP简介TCP的连接机制是面向连接,TCP通过三次握手机制完成连接,三次握手机制,三次握手保证双方确认准备好发送数据和接收数据,并且能够确保按顺序准确无误的发送数据。TCP非常可靠,它能够确保传输数据时丢失的数据能够重新发送,若发送方发出数据后没有在规定时间内收到确认,发送方将......
  • wordpress二开-WordPress新增页面模板-说说微语
    微语说说相当于一个简单的记事本,使用还是比较方便的。这个版本的说说微语CSS样式不兼容,可能有些主题无法适配,但是后台添加内容,前端显示的逻辑已经实现。可以当作Wordpress二开中自定义页面模板学习~一、后台添加说说微语模块首先我们把以下代码,添加到主题根目录中的funct......
  • 【DP优化技巧】1. Max类DP
    有的时候在遇到问题时,不妨换一个角度,100%不会吃亏\[\begin{align*}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&----LYJ\end{align*}\]有时,在想办法优化DP时,如果遇到了一些像\(A\)和......
  • HDOJ 1421 搬寝室 线性dp
    #include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=2010,M=1010,MAX=-1;inta[N];intdp[M][N];signedmain(){ intn,m; while(cin>>n>>m) { for(inti=1;i<=n;i++)cin>>a[i]; sort(a+1,......
  • dpdk ppp丢包排查
    在 openEuler 系统运行 DPDK 时,若 PPE(PacketProcessingEngine) 中的 PPP(PacketProcessingPipeline) 处理逻辑为“查表后丢弃所有包”,可能是由于以下几种情况导致的。下面分析可能的原因及对应的解决方案: 1. 流表查找未命中(表项缺失或匹配失败)现象:PPP 根据预定......
  • addPermissionForUser方法
    @Transactional(rollbackFor=Exception.class)public  voidaddPermissionForUser(StringuserName,ListuserPermissionDTOList){if(CollectionUtils.isEmpty(userPermissionDTOList)){return;for(UserPermissionDTOuserPermissionDTO:userPermissionDTOList){I......
  • 1(4)计数器
    Proteus仿真计数器工程搭建计数器从0计数到15,当计数到10时触发led灯代码:点击查看代码`timescale1ns/1ps////////////////////////////////////////////////////////////////////////////////////Company://Engineer:////CreateDate:2024/11/2115:41:56/......
  • CF889E Mod Mod Mod DP
    对于一个x我们发现最多只有\(\log\)次有效取模,但没啥用。我们发现\(dp\)数组(函数)是一个分段一次函数(等差数列),然后从第一个\(a_i\)开始考虑,发现每次只会多出一条线段(就是\(a_i-1\)这条)其他线段会翻折到下面,对于一条线段只会进行\(\loga\)次翻折,所以对线段的操作总次数......