操作序列:简单的二维 dp。

观察

我们每次操作可以让 \(x\) 变为 \(2x-1\),或者当 \(x\) 为奇数时让 \(x\) 变为 \(\frac{x+1}{2}\)。

显然,执行第一种操作,会使 \(x\) 变成奇数。

那一旦我们连续执行两次操作,\(x\) 就会变为:

\[\frac{(2x+1)-1}{2}=\frac{2x}{2}=x
\]

也就是说,当 \(x\) 为奇数时,这两个操作互逆。当 \(x\) 为偶数时,无法操作。

因此,在任何时候,第一次操作的次数都要大于等于第二次操作的次数。这像极了括号匹配,任何时候左括号必须大于右括号。

其中左括号是操作 \(1\),右括号是操作 \(2\)。

dp 设计

于是我们可以先在 \(x\) 为奇数时把 \(x\) 不断执行第二种操作直到变成偶数,相当于往栈里丢了几个左括号。

然后接下来我们对每次操作考虑,定义 \(dp_{i,j}\) 表示考虑前 \(i\) 位,目前栈里有 \(j\) 个左括号的方案数。

然后很显然的转移:

\[dp_{i,j}=\sum_{j=1}^{n+s}dp_{i-1,j-1}+\sum_{j=0}^{n+s-1}dp_{i-1,j+1}
\]

其中 \(s\) 表示一开始加进栈里面的左括号个数。

时间复杂度 \(O(n^2)\),可过。

其实这题可以用滚动数组优化,但是不用滚动数组仍然可以过。因为我懒,就不写滚动数组了。

特判

注意到当最后 \(x\) 能变成 \(1\) 时,无论何时使用操作 \(1\) 或者操作 \(2\) 都可以。于是此时答案就是 \(2^n\)。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
const ll mod=998244353;
ll dp[5005][6005],n,s,ans=0;
int main()
{
freopen("op.in","r",stdin);
freopen("op.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>s;
int tmp=s,qs=0;
while(tmp%2==1&&tmp>1)
{
tmp=(tmp+1)/2;
qs++;
}
if(tmp!=1)
{
dp[0][qs]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=6000;j++)
{
dp[i][j]=(dp[i-1][j-1]+dp[i][j])%mod;
}
for(int j=0;j<=6000;j++)
{
dp[i][j]=(dp[i][j]+dp[i-1][j+1])%mod;
}
}
for(int i=0;i<=6000;i++)ans=(ans+dp[n][i])%mod;
cout<<ans%mod;
return 0;
}
dp[0][0]=1;
for(int i=1;i<=n;i++)dp[i][0]=(dp[i-1][0]*2)%mod;
cout<<dp[n][0];
return 0;
}

坑点

dp 转移上限不能直接设为 \(n\),因为一开始会多丢 \(\log\) 个左括号进去。

Hetao P1391 操作序列 题解 [ 绿 ] [ 二维线性 dp ]的更多相关文章

  1. Vijos1392拼拼图的小衫[背包DP|二维信息DP]

    背景 小杉的幻想来到了经典日剧<死亡拼图>的场景里……被歹徒威胁,他正在寻找拼图(-.-干嘛幻想这么郁闷的场景……). 突然广播又响了起来,歹徒竟然又有了新的指示. 小杉身为新一代的汤浅, ...

  2. UVA1347 旅游(二维递归DP)

    旅游 [题目链接]旅游 [题目类型]DP &题解: 紫书P269 代码很简单,但思路很难.很难能想到要把一个圈分成2条线段,很难想到d(i,j)表示的是已经走过max(i,j)还需要的距离值, ...

  3. 二维线性表 list实现

    class Coordinate{ private int x; private int y; } List<Coordinate> list=new ArrayList<Coord ...

  4. 棋盘分割(二维区间DP)

    题目大意:给一个棋盘,棋盘上每个格子中都有一个值,现在需要将棋盘切成n个矩形,总共切n-1刀,求最小的均方差.均方差定义为:,其中. 题目分析:将均方差化简得到:均方差2=(Σxi2)/n-平均值2. ...

  5. 在UniApp的H5项目中,生成二维码和扫描二维码的操作处理

    在我们基于UniApp的H5项目中,需要生成一些二维码进行展示,另外也需要让用户可以扫码进行一定的快捷操作,本篇随笔介绍一下二维码的生成处理和基于H5的扫码进行操作.二维码的生成,使用了JS文件wea ...

  6. HDU 4819 Mosaic 二维线段树

    Mosaic Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  7. poj2155二维树状数组

    Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row an ...

  8. Android应用--QR的生成(二维码)

    二维码的定义: 二维码(2-dimensional bar code),是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的. 在许多种类的二维条码中,常用的码制 ...

  9. 低差异序列 (low-discrepancy sequences)之Halton序列均匀产生多维随机数的介绍与实现

    Halton序列 在统计学中,Halton序列是用于生成空间中的点的序列,如Monte Carlo模拟的数值方法,虽然这些序列是确定性的,但它们的差异性很低,也就是说,在许多方面看起来是随机的.它们在 ...

  10. PHP二维码生成的方法(google APi,PHP类库,libqrencode等)

    原文地址: http://blog.csdn.net/liuxinmingcode/article/details/7910975 ================================== ...

随机推荐

  1. pikachu文件上传_2024-11-26

    什么是文件上传漏洞 文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像.上传附件等等.当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型.后缀名.大小等等,然后 ...

  2. bat隐藏窗口运行

    在bat脚本开头添加: if "%1" == "h" goto begin mshta vbscript:createobject("wscript. ...

  3. 金仓数据库数据迁移实战:从MySQL到KES的顺利迁移

    今天我们将开始实践金仓数据库的数据迁移功能.在此之前,我们一直使用的是简化版的 Docker 镜像,这个版本并没有集成可视化操作工具.因此,为了更方便地进行后续的操作,我们需要额外下载一个 Windo ...

  4. Kettle设置定时跑任务

    1.Kettle设置作业 保存,test.kjb 2. 创建批处理 zxjb.bat C: cd C:\kettle\pdi-ce-9.4.0.0-343\data-integration kitch ...

  5. .net core 文本比对的一个诡异设计

    9-11 发现的,过久了都忘了,记一下 string s = Encoding.ASCII.GetString(new byte[] { 0x57, 00, 0x49, 00, 0x4e, 00, 0 ...

  6. 【C#】接口的基本概念

    目录 基本 什么是接口 接口与抽象类的区别 抽象类 接口 实例 设计接口 基本 什么是接口 C#接口(interface)是:用来定义一种程序的协定 实现接口的类或者结构要与接口的定义严格一致. 有了 ...

  7. 如何使用Jet家软件进行学习(intellij、idea、IDEA、Pycharm……)

    如何使用Jet家软件进行学习 本文档提供方法只用于学习研究,不得用于其他用途 以下,萌狼蓝天将会提供两种方式 目录 如何使用Jet家软件进行学习 第一种方式:使用EAP版本 第二种方式:使用插件 (1 ...

  8. docker-compose network名称定义

    docker-compose启动的网络名称: 1.没有自定义网络名 $ cat docker-compose.yaml version: '2' services: zookeeper1: image ...

  9. Qt编写机器码秘钥控制/日期防篡改/离线使用/硬件标识/运行时间/数量控制/批量更新秘钥

    一.前言说明 搞软件开发一直追求精益求精的目标,从第一版的秘钥生成器到今天这个版本,经历了十年的时间,最初的版本做的非常简陋,就是搞了个异或加密,控制运行时间,后面又增加设备数量的控制,然后就是到期时 ...

  10. _findnext()调试中断,发生访问错误,错误定位到ntdll.dll

    问题: 采用_findfirst和_findnext获取指定的文件夹下的文件时,_findnext()函数在调试时发生中断,发生访问错误,错误定位到ntdll.dll.错误提示如下所示: _findn ...