首页 > 其他分享 >AGC017F Zigzag【状压 DP】

AGC017F Zigzag【状压 DP】

时间:2022-10-23 09:55:41浏览次数:69  
标签:位置 int 状压 Zigzag ++ 折线 当前 DP

传送门


以下认为 \(n,m\) 同阶。

首先,我们可以根据每次走的方向用一个二进制数来表示一条折线。这样显然有一个傻逼 DP,设 \(f_{i,S}\) 表示已经确定了前 \(i\) 条折线,其中第 \(i\) 条折线的状态为 \(S\) 的方案数,这样复杂度是 \(O(4^n \text{poly}(n))\) 的。

注意到这个转移的形式和轮廓线 DP 十分类似,于是我们可以使用同样的方式优化:先按照折线从左到右,再按照每条折线从上到下依次确定,那么上一条折线中比当前点往前的部分都不用考虑了。于是我们可以修改一下 DP 的定义,设 \(f_{i,j,k,S}\) 已经确定了前 \(i\) 条折线和第 \(i+1\) 条折线的前 \(j\) 个位置,第 \(i\) 条折线在当前层和当前位置距离为 \(k\)、后半部分为 \(S\) 的 \(j+1 \sim n\) 位,当前折线的前半部分为 \(S\) 的 \(1 \sim j\) 位,在这种情况下的方案数。其中 \(i,j\) 两位都可以滚掉,但总时间复杂度 \(O(2^n n^3)\),还是过不去。

上面做法的瓶颈在于,在抹掉上一条折线的前半部分时我们把它的位置信息也给抹掉了,这时候我们不得不多用一个状态 \(k\) 来确定它的位置。如果,我们能够在抹除上一条折线的前半部分的同时利用当前折线确定出位置,是不是就大功告成了?

顺着这个思路我们继续往下想。如果执意要完整记录下上一条折线的话,看起来并没有很好的解决方案。但是仔细想想,我们其实只关心上一条折线限制了当前折线的哪些位置,而对于一些不可能走到的位置,其实可以不记录那些状态。也就是说,我们把上一条折线右侧的区域,和这条折线未来可能走到的区域,取个交,对答案也没有影响。

从官方题解里贺来的图:

于是我们可以认为上一条折线是直接从当前位置出发的,而当前位置可以直接由 \(S\) 确定,这样就把 \(k\) 给扔掉了。

我们修改一下 DP 的定义:设 \(f_{i,j,S}\) 表示已经确定了前 \(i\) 条折线和第 \(i+1\) 条折线的前 \(j\) 个位置,满足如下条件的方案数:当前折线的前 \(j\) 个位置恰好为 \(S\) 的 \(1 \sim j\) 位,且在之后的过程中,当前折线不能走到折线 \(S\) 的左边。

考虑如何转移,我们设上一条折线对当前折线的限制为 \(P = (p_1,\cdots,p_{n-1})\),当前折线为 \(Q = (q_1,\cdots,q_k)\),显然 \(\forall i \in [1,k),p_i = q_i\)。转移有两种情况:

  • 若 \(q_k = p_k\),那么不需要对 \(P\) 进行修改。

  • 否则一定有 \(q_k = 1\) 且 \(p_k = 0\)。如果不存在 \(i > k\) 使得 \(p_i = 1\),那么我们将 \(p_k\) 修改为 \(1\)。否则,找到最小的这样的 \(i\),将 \(p_k\) 修改为 \(1\),将 \(p_i\) 修改为 \(0\) 即可。可以结合图片理解这个过程。

上述操作都可以利用二进制操作在 \(O(1)\) 时间内完成。\(i,j\) 两维都可以滚掉,总时间复杂度为 \(O(2^n n^2)\)。

code
/*
挥拂去蒙尘半生的晦暗
用这嶙峋双臂迎接 振翅吧 我的蝴蝶
最后一支 赤诚赞歌盘旋
潮起潮落翻覆昼夜 澎湃在生命刻度之前
此刻色彩挣脱谎言 献予你 赤红纸花遍野
*/
#include <bits/stdc++.h>
using namespace std;

const int N = 20, mod = 1e9 + 7;

int n, m, k, t[N][N], f[2][1 << N];
void add(int &x, int y) { x += y; if (x >= mod) x -= mod; }

int main() {
    ios :: sync_with_stdio(0);
    cin >> n >> m >> k; --n;
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++) 
            t[i][j] = -1;
    for (int i = 1, a, b, c; i <= k; i++) {
        cin >> a >> b >> c;
        t[--a][--b] = c;
    }
    int o = 0;
    f[o][0] = 1;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) { 
            o ^= 1;
            for (int S = 0; S < 1 << N; S++) f[o][S] = 0;
            for (int S = 0; S < 1 << N; S++) if (f[o ^ 1][S]) {
                int v = f[o ^ 1][S];
                if (t[i][j] != 1) {
                    if (~S >> j & 1) add(f[o][S], v);
                }
                if (t[i][j] != 0) {
                    if (S >> j & 1) add(f[o][S], v);
                    else {
                        int T = S >> j;
                        if (T) T &= T - 1;
                        T = (T + 1) << j | (S & ((1 << j) - 1));
                        add(f[o][T], v);
                    }
                }
            }
        }
    }
    int ans = 0;
    for (int S = 0; S < 1 << N; S++) add(ans, f[o][S]);
    cout << ans << endl;
    return 0;   
}

标签:位置,int,状压,Zigzag,++,折线,当前,DP
From: https://www.cnblogs.com/came11ia/p/16817290.html

相关文章

  • 传输层之UDP与TCP的首部
    从通信信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能的最底层。传输层位于应用层和数据链路层之间,主要有两个协议,用......
  • 优化 WordPress 数据库,提高 WordPress 速度
    WordPress的机制是主要使用wp_posts表来存储所有数据,包括日志,页面,附件,导航菜单等等,所以WordPress使用了一定时间之后,数据量一大还是有点慢,除了对WordPress进行全方......
  • 记一次SpringBoot整合WebSocket 找不到ServerEndpointExporter类的问题
    packagecom.mengxiangnongfu.cms.framework.configure;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Confi......
  • java第四讲-继承与多态-InheritsAndPolymorphismSourceCode
    1.继承条件下类的访问权限public:外界可自由访问;private:外界不可访问;protected:同一包中的子类都可以访问,另一包中的子类(派生于同一个父类)也可以访问;default:如果......
  • WordPress
    主题目录结构assets存放imgcssjsfontfront-page 主页get_header()get_footer()调用头部与脚部header头部footer脚部functions函数文件sing......
  • 单调队列优化dp(1)(P2034 选择数字)
    参考算法学习笔记(66):单调队列-知乎(zhihu.com)题目描述给定一行n个非负整数a[1]..a[n]。现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择。你的任务是......
  • Apple Low Power DisplayPort(ALP_DP)学习随笔
     edp是PC内置显示接口的主流标准,主用于笔记本电脑或PAD上,普遍用于中大尺寸PANEL。 系统架构如下:     apple 的ALP_DP 源于edp1.4(edp1.4又是源于DPV1.2a......
  • AcWing80 骰子的点数(线性dp)
    #definepbpush_backclassSolution{public:vector<int>numberOfDice(intn){intf[15][100];//投i次,总和为j的投掷可能memset(f,0,sizeof(......
  • WordPress彻底禁用上传媒体图片自动生成缩略图及多尺寸图片(亲测可用)
    WordPress默认上传图片的时候会自动生成缩略图及多尺寸的图片文件,大部分网站都用不到这些多余的图片,不仅仅占用空间,而且上传的时候还会消耗额外的性能。下面仅需两段函数......
  • ST/意法STTH1506DPI车规FRD,原厂渠道ASEMI代理
    编辑-ZST/意法STTH1506DPI车规FRD参数:型号:STTH1506DPI重复峰值反向电压(VRRM):600V平均正向电流(IF):15A浪涌非重复正向电流(IFSM):130A储存温度范围(Tstg):-65to﹢150℃工作结......