题意:有两个序列,序列中数字$\in\{-1,0,1\}$

有两个指针,初始时分别指向两个序列的开始位置,有一个初始为$0$的数$a$,重复以下过程直到两个指针都指向序列末尾后

如果一个指针指向末尾后,那么移动另一个指针

否则如果$a>0$,随机移动一个指针

否则如果至少一个指针指向$1$,随机移动一个指向$1$的指针

否则随机移动一个指针

每移动一个指针,就把这个指针指向的数加到$a$上

问有多少种填$0$为$\pm1$的方法使得任何时候都有$a\geq0$

首先是对填好的序列进行判定,在两个序列中分别找到以$-1$结尾的最小前缀和$s_a,s_b$(如果序列全为$1$就选择总和),如果两个序列都满足这个最小前缀和$\ne$总和,那么条件是$s_a+s_b\geq-1$(因为两个$-1$后面一定都紧跟着一个$1$,而后面的前缀和不会更小,所以可以满足),否则需要满足$s_a+s_b\geq0$(一个序列的指针已经到了末尾后,只能被强迫移动另一个指针)

现在要DP,正着DP很困难,考虑倒着DP,这样每次只会增加一个小前缀

设$f_{i,j,k}$表示填完$[i,n]$,这些位置相对于$i$的前缀和中,以$-1$结尾的最小前缀和$=j$的方案数,$k$表示$j$是否等于总和

如果$i-1$位可以填$1$,那么有$f_{i,j,0}\rightarrow f_{i-1,j+1,0},f_{i,j,1}\rightarrow f_{i-1,j+1,1}$,因为在最前面加一个$1$并不改变原来的最小前缀和

如果$i-1$位可以填$-1$,那么有$f_{i,j,0}\rightarrow f_{i-1,\min(-1,j-1),0},f_{i,j,1}\rightarrow f_{i-1,\min(-1,j-1),[j\le0]}$,因为增加了一个值为$-1$的前缀和,所以原来$j>0$且最小前缀和$=j$的方案会变为最小前缀和$=-1\ne j-1$

对两个序列分别DP后直接统计答案即可

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef int pr[2];
const int mod=998244353;
int mul(int a,int b){return(ll)a*b%mod;}
void inc(int&a,int b){(a+=b)>=mod?a-=mod:0;}
struct str{
	char s[5010];
	int n;
	pr _f[10010],_g[10010],*f=_f+5000,*g=_g+5000;
	void work(){
		int i,j;
		scanf("%s",s+1);
		n=strlen(s+1);
		f[0][1]=1;
		for(i=n;i>0;i--){
			memset(_g,0,sizeof(_g));
			for(j=-n;j<=n;j++){
				if(s[i]!='P'){//+
					inc(g[j+1][0],f[j][0]);
					inc(g[j+1][1],f[j][1]);
				}
				if(s[i]!='V'){//-
					inc(g[min(-1,j-1)][0],f[j][0]);
					inc(g[min(-1,j-1)][j<=0],f[j][1]);
				}
			}
			memcpy(_f,_g,sizeof(_g));
		}
	}
}a,b;
int main(){
	int i,j,s;
	a.work();
	b.work();
	s=0;
	for(i=-a.n;i<=a.n;i++){
		for(j=-b.n;j<=b.n;j++){
			if(i+j>=-1)inc(s,mul(a.f[i][0],b.f[j][0]));
			if(i+j>=0){
				inc(s,mul(a.f[i][0],b.f[j][1]));
				inc(s,mul(a.f[i][1],b.f[j][0]));
				inc(s,mul(a.f[i][1],b.f[j][1]));
			}
		}
	}
	printf("%d",s);
}

[xsy3343]程序锁的更多相关文章

  1. CAD调试时抛出“正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码”异常的解决方法

    这些天重装了电脑Win10系统,安装了CAD2012和VS2012,准备进行软件开发.在调试程序的时候,CAD没有进入界面就抛出 “正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain ...

  2. 正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样...

    出错提示: 正尝试在 OS 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 原因分析: .NET2.0中增加了42种非常强大的调试助手 ...

  3. 检测到 LoaderLock:DLL"XXXX"正试图在OS加载程序锁内执行

    解决方法: ctrl+D+E或alt+ctl+e或使用菜单调试——>异常——>异常窗口——>Managed Debugging Assistants——>去掉LoaderLoc ...

  4. 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码

    来自:http://www.cnblogs.com/lcxu2/archive/2011/01/16/2004016.html 正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain 或 ...

  5. android149 360 程序锁输入密码

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  6. android147 360 程序锁fragment

    package com.itheima.mobileguard.fragment; import java.util.ArrayList; import java.util.List; import ...

  7. android147 360 程序锁

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  8. Android安全问题 程序锁

    导读:本文介绍如何实现对应用加锁的功能,无须root权限 某些人有时候会有这样一种需求,小A下载了个软件,只是软件中的美女过于诱惑与暴露,所以他不想让别人知道这是个什么软件,起码不想让别人打开浏 览. ...

  9. 正尝试在 OS 载入程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内执行托管代码,这样做会导致应用程序挂起。

    出错提示: 正尝试在 OS 载入程序锁内执行托管代码. 不要尝试在 DllMain 或映像初始化函数内执行托管代码,这样做会导致应用程序挂起. 原因分析: .NET2.0中添加了42种非常强大的调试助 ...

随机推荐

  1. 无需登录-悟空CRM 存储型XSS

    无需登录-悟空CRM 存储型XSS 审计悟空的缘由是看见某云爆出CRM的getshell,于是就想着去挖出来瞅瞅!但可能自己把自己给局限了,就想着去挖那些无限制访问的文件. 故事的发生点 漏洞文件:/ ...

  2. python装饰器三种装饰模式的简单理解

    学设计模式中有个装饰模式,用java实现起来不是很难,但是远远没有python简单,难怪越来越火了! 这里就简单讨论下python的几种装饰模式: 一 无参装饰器: # 装饰器 import time ...

  3. js实现数据视图双向绑定原理

    这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了几行代码看他 ...

  4. 洛谷P2002消息扩散

    传送门啦 这个题就是tarjan强连通分量与入度的例题了. 思路: 利用缩点的思想,先预处理一下所有的强连通分量,然后把每个强连通分量内的所有节点看做一个节点,然后处理一张新图,然后检查每个点的入度, ...

  5. python_selenium自动化测试框架

    设计思路 本文整理归纳以往的工作中用到的东西,现汇总成基础测试框架提供分享. 框架采用python3 + selenium3 + PO + yaml + ddt + unittest等技术编写成基础测 ...

  6. linux 系统网卡无法识别,缺少驱动

    #linux网卡驱动安装# Linux设备加载 #lsmod Module Size Used by e1000e 查看硬件设备 ls /usr/share/hwdata 查看pci网卡设备 lspc ...

  7. cross apply 和 outer apply

    使用APPLY运算符可以实现查询操作的外部表表达式返回的每个调用表值函数.表值函数作为右输入,外部表表达式作为左输入. 通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出.A ...

  8. 搜索入门之dfs--经典的迷宫问题解析

    今天来谈一下dfs的入门,以前看到的dfs入门,那真的是入门吗,都是把dfs的实现步骤往那一贴,看完是知道dfs的步骤了,但是对于代码实现还是没有概念.今天准备写点自己的心得,真的是字面意思--入门. ...

  9. hdu 2069 1 5 10 25 50 这几种硬币 一共100个(母函数)

    题意: 有50 25 10 5 1 的硬币 一共最多有100枚 输入n输出有多少种表示方法 Sample Input1126 Sample Output413 # include <iostre ...

  10. day7 socket网络编程

    Python Socket网络编程 Socket是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于Socket来完成通信的 ...