5.15 牛客挑战赛40 C 小V和字符串 数位dp 计数问题
LINK:小V和字符串
容易想到只有1个数相同的 才能有贡献。
知道两个01串 那么容易得到最小步数 大体上就是 第一个串的最前的1和第二个串最前的1进行匹配。
容易想到设f[i][j]表示 前i位1的个数为j的贡献.
不过在 j-1 向 j进行转移的时候 两个集合的贡献无法得到 因为我们只知道其中一个串的最后一个1的位置。
考虑如果每次合并集合时 只统计最后一个1的贡献 那么这样无论怎么做都是错误的。
回到先前 还是考虑描绘出两个串长什么样子 然后 考虑如何统计答案。
问题变成了 逐位考虑 统计两个串的贡献。
那么先前那个匹配的工程就变成了对于每个前缀 1的数量是否相等 不相等 其中一个串的1要整体向右移动 不断进行这样的匹配即可。
这样我们就可以逐位得到贡献 累计上方案数就可以得到答案了。
值得一提的是 要记录其1的差值 下标为负可以进行调整。
由于两个串的贡献都会被统计两次 所以要除以2.
const int MAXN=1010,INV=(1+mod)>>1;
int n,m,maxx;
char a[MAXN];
int f[MAXN][MAXN][2][2];//方案数
int g[MAXN][MAXN][2][2];//答案
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline int mus(int x,int y){return x-y<0?x-y+mod:x-y;}
inline int mul(int x,int y){return (ll)x*y%mod;}
int main()
{
freopen("1.in","r",stdin);
gc(a);n=strlen(a+1);
f[0][502][1][1]=1;m=n>>1;
rep(1,n,i)
{
rep(max(-i,-m),min(i,m),j)
{
int cc=j+502;
rep(0,1,l)
rep(0,1,r)
{
int w1=l==1?a[i]-'0':1;
int w2=r==1?a[i]-'0':1;
//两者都为0
f[i][cc][l==1&&w1==0][r==1&&w2==0]=add(f[i][cc][l==1&&w1==0][r==1&&w2==0],f[i-1][cc][l][r]);
g[i][cc][l==1&&w1==0][r==1&&w2==0]=add(g[i][cc][l==1&&w1==0][r==1&&w2==0],add(g[i-1][cc][l][r],mul(f[i-1][cc][l][r],abs(j))));
//两者都为1
if(w1&&w2)
{
f[i][cc][l==1&&w1==1][r==1&&w2==1]=add(f[i][cc][l==1&&w1==1][r==1&&w2==1],f[i-1][cc][l][r]);
g[i][cc][l==1&&w1==1][r==1&&w2==1]=add(g[i][cc][l==1&&w1==1][r==1&&w2==1],add(g[i-1][cc][l][r],mul(f[i-1][cc][l][r],abs(j))));
}
//第一个串为1.
if(w1)
{
f[i][cc+1][l==1&&w1==1][r==1&&w2==0]=add(f[i][cc+1][l==1&&w1==1][r==1&&w2==0],f[i-1][cc][l][r]);
g[i][cc+1][l==1&&w1==1][r==1&&w2==0]=add(g[i][cc+1][l==1&&w1==1][r==1&&w2==0],add(g[i-1][cc][l][r],mul(f[i-1][cc][l][r],abs(j+1))));
}
if(w2)
{
f[i][cc-1][l==1&&w1==0][r==1&&w2==1]=add(f[i][cc-1][l==1&&w1==0][r==1&&w2==1],f[i-1][cc][l][r]);
g[i][cc-1][l==1&&w1==0][r==1&&w2==1]=add(g[i][cc-1][l==1&&w1==0][r==1&&w2==1],add(g[i-1][cc][l][r],mul(f[i-1][cc][l][r],abs(j-1))));
}
}
}
}
put(mul(INV,add(add(g[n][502][0][0],g[n][502][0][1]),add(g[n][502][1][0],g[n][502][1][1]))));
return 0;
}
5.15 牛客挑战赛40 C 小V和字符串 数位dp 计数问题的更多相关文章
- 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治
LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...
- 5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
LINK:小V的序列 考试的时候 没想到正解 于是自闭. 题意很简单 就是 给出一个序列a 每次询问一个x 问序列中是否存在y 使得x^y的二进制位位1的个数<=3. 容易想到 暴力枚举. 第一 ...
- 牛客练习赛40 A 小D的剧场 (思维dp)
链接:https://ac.nowcoder.com/acm/contest/369/A 题目描述 若你摘得小的星星 你将得到小的幸福 若你摘得大的星星 你将得到大的财富 若两者都能摘得 你将得到 ...
- 牛客练习赛40 C 小A与欧拉路(树的直径)
链接:https://ac.nowcoder.com/acm/contest/369/C 题目描述 小A给你了一棵树,对于这棵树上的每一条边,你都可以将它复制任意(可以为0)次(即在这条边连接的两个点 ...
- 牛客挑战赛 30 A 小G数数
题目链接:https://ac.nowcoder.com/acm/contest/375/A 分析:我写的时候竟然把它当成了DP....... 还建了个结构体DP数组,保存一二位,不知道当时脑子在抽啥 ...
- 牛客挑战赛40 VMware和基站 set 二分 启发式合并 区间覆盖
LINK:VMware和基站 一道 做法并不常见的题目 看起来很难写 其实set维护线段就可以解决了. 容易想到 第二个操作借用启发式合并可以得到一个很不错的复杂度 不过利用线段树维护这个东西 在区间 ...
- 【牛客挑战赛30D】小A的昆特牌(组合问题抽象到二维平面)
点此看题面 大致题意: 有\(S\)张无编号的牌,可以将任意张牌锻造成\(n\)种步兵或\(m\)种弩兵中的一种,求最后步兵数量大于等于\(l\)小于等于\(r\)的方案数. 暴力式子 首先我们来考虑 ...
- 2019牛客多校第七场H Pair 数位DP
题意:给你一个3个数A, B, C问有多少对pair(i, j),1 <= i <= A, 1 <= j <= B, i AND j > C或 i XOR j < ...
- 牛客多校第七场H Pair 数位dp理解
Pair 题意 给出A B C,问x取值[1,A]和y取值[1,B]存在多少组pair<x,y>满足以下最小一种条件,\(x \& y >c\),\(x\) xor \(y& ...
随机推荐
- 状压DP之学校食堂
题目 传送们 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负 ...
- 区间DP之凸多边形的三角剖分
题目 给定一具有N个顶点(从1到N编号)的凸多边形,每个顶点的权均已知.问如何把这个凸多边形划分成N-2个互不相交的三角形,使得这些三角形顶点的权的乘积之和最小? 输入 第一行 顶点数N(N<5 ...
- 从0开始,手把手教你用Vue开发一个答题App
项目演示 项目演示 项目源码 项目源码 教程说明 本教程适合对Vue基础知识有一点了解,但不懂得综合运用,还未曾使用Vue从头开发过一个小型App的读者.本教程不对所有的Vue知识点进行讲解,而是手把 ...
- python读取EXCEL是去掉空白行和表头全部重命名
当读取进来的表格如图所示,转换成图2. import pandas as pd # header:指定作为列名的行,默认0,即取第一行的值为列名.数据为列名行以下的数据:若数据不含列名, # 则设定 ...
- 记一次线上服务CPU 100%的处理过程
告警 正在开会,突然钉钉告警声响个不停,同时市场人员反馈客户在投诉系统登不进了,报504错误.查看钉钉上的告警信息,几台业务服务器节点全部报CPU超过告警阈值,达100%. 赶紧从会上下来,SSH登录 ...
- python 面向对象专题(十):特殊方法 (三)__get__、__set__、__delete__ 描述符(三)方法是描述符
在类中定义的函数属于绑定方法(bound method),因为用户定义的函数都有 __get__ 方法,所以依附到类上时,就相当于描述符.示例 20-13 演示了从 面向对象专题(九)示例 20-8 ...
- scrapy 源码解析 (二):启动流程源码分析(二) CrawlerProcess主进程
CrawlerProcess主进程 它控制了twisted的reactor,也就是整个事件循环.它负责配置reactor并启动事件循环,最后在所有爬取结束后停止reactor.另外还控制了一些信号操作 ...
- 数据结构C语言实现----清空、销毁一个栈
代码如下: #include<stdio.h> #include<stdlib.h> typedef struct { char *base; char *top; int s ...
- 使用 maven 创建项目模板
前言 配置 demo 工程 生成模板 生成项目 上传模板到仓库 参看链接 前言 微服务的概念越来越流行,随着服务粒度越来越细,拆分的模块越来越明确,我们的工程项目也变得越来越多. 有时候一个项目搭建, ...
- 利用CloudFlare自动DDNS
注意要 仅限 DNS 获取咱的Key https://dash.cloudflare.com/profile 先在控制面板找到咱的目前IP,然后到Cloudflare中新建一个A记录,如:ddns.y ...