首页 > 其他分享 >P4965 题解

P4965 题解

时间:2022-09-27 15:22:05浏览次数:76  
标签:字符 des int 题解 P4965 添加 text dp

题目传送门

被同机房神犇使用一顿晚饭的时间爆切并当成作业布置给我的题...

虽然是紫,但实际难度处于可以接受的范围内。

题目分析

开始的思路是 \(\text{set}\) 乱搞,因为发现对于每一次操作,如果执行那么一定会对前面的字符串有影响,所以直接放进 \(\text{set}\) 判重,最后输出元素个数即可。

但是这样要记录上一次处理时的状态,实现起来会很怪,而且复杂度似乎不是很对,所以最后就放弃了。


但是有刚刚的尝试,不难想到正解:动态规划

在定义状态方面,我原来选择的是二维,用 \(dp_{i,0}\) 表示不选择第 \(i\) 个操作,\(dp_{i,1}\) 表示选择,看它们可能得到的字符串数量。

但是后来发现可以直接压一维,直接用 \(dp_i\) 就可以了。


由于删除操作明显异于加入任何一个字符,所以进行分类讨论。

  • 添加字符
  1. 新添加的字符没有被出现过

这种情况下不会出现与之前重复的字符串,所以直接乘就可以了。

\[dp_i = dp_{i-1} \times 2 \]

  1. 新添加的字符已经出现过

开始没有专门考虑这种情况,而是想办法用其他东西,比如刚刚提到的 \(\text{set}\) 判重。

但是这个东西可以直接放到状态转移方程里面。

我们考虑记录每一个字符最后出现的位置,记为 \(des\)。那么可以推出,需要去的重复个数就是 \(dp_{des - 1}\)。

为什么?我也不知道

所以我去问了 @yinhee 神犇(也是作业布置者),搞明白了原理。由于这个字符已经出现过,所以在第 \(des\) 个操作出现时,第 \(des\) 到 \(i - 1\) 可以不执行,这样该字符串的末尾并不会改变。所以这一部分是需要去掉的,即可得出:

\[dp_i = dp_{i-1} - dp_{des-1} \]

  • 删除字符
  1. 此前执行过添加字符

此时无论干什么,求出的都一定是重复的情况,不用记录。

\[dp_i = dp_{i-1} \]

  1. 此前没有执行过添加字符

如果我们操作了 \(x\) 次删除字符,如果 \(x \le n-1\) ,那么就可以得到一种新情况。

\[dp_i = dp_{i-1} + 1 \]

  • 特殊处理

这种其实最好想,即一个字符如果刚被删除就被加到了最后,这种情况没有被前面任何一种情况包括进去,单独处理即可。

贴上代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=19260817;
const int maxn=5000005;
int n,m,a[30];
int cnt;
int dp[maxn];
string s,u;
inline void init(){
	cin>>n>>m;
	cin>>s>>u;s=" "+s;u=" "+u;
	dp[0]=1;
}
signed main(){
	init();
	for(register int i=1;i<=m;++i){
		if(u[i]=='u'){ //是删除 
			if(cnt<n){
				dp[i]=dp[i-1]+1;
				a[s[n-cnt]-'A'+1]++;
			}
			else dp[i]=dp[i-1];
			cnt++;
		}
		else{ //不是
			dp[i]=dp[i-1]*2%mod;
			dp[i]=(dp[i]-a[u[i]-'A'+1]+mod)%mod;
			a[u[i]-'A'+1]=dp[i-1];
		}
	}
	cout<<dp[m]%mod;
}

标签:字符,des,int,题解,P4965,添加,text,dp
From: https://www.cnblogs.com/yizhixiaoyun/p/16734484.html

相关文章

  • AtCoder ABC 270 题解(D-F)
    AtCoderABC270题解(D-F)D-Stones(博弈DP)题目:​ 现在有一堆石子,一个序列a表示每次可以从石头里拿走多少个石子。当无法再拿出石头的时候,游戏结束。两边都以最佳策略......
  • 题解【CF1436E Complicated Computations】
    CF1436EComplicatedComputations解题报告。不一定更好的阅读体验。对于一个数\(x\),考虑什么条件\(x\)可以作为答案。首先要满足\(\forally\in[1,x)\),\(y\)......
  • SpringBoot+Mybatis-Plus 数据表字段是关键字的问题解决
    如果字段名是关键字,用mybatisplus时会报以下错误:badSQLgrammar[];nestedexceptionisjava.sql.BatchUpdateException:ORA-01747:user.table.column,table.column......
  • 力扣算法第1题--两数之和(暴力题解&优化题解)
    两数之和题目描述:给定一个整数数组nums 和一个整数目标值target,请你在该数组中找出和为目标值target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输......
  • P2044 随机数生成器 题解
    这么标准的不动点居然只有一篇不动点题解?而且唯一的不动点题解关于不动点的描述还是错的?所以,来写一篇题解讲讲,MO中是怎么弄这种一阶线性递推式的。单个数,虽然省常数,却......
  • P6835 [Cnoi2020]线形生物 题解
    通过这道题可以看出来pz根本不会期望考虑期望线性性质,设\(E_{x\toy}\)表示从\(x\)走到\(y\)的期望步数,那么有\(E_{1\ton+1}=\sum_{i=1}^nE_{i\toi+1}\),因此考......
  • P2569 [SCOI2010]股票交易 题解
    设\(f_{i,j}\)表示第1天至第\(i\)天,手上有\(j\)股股票时拥有的最多钱。考虑转移,首先就有\(f_{i,j}=-j\timesap_i\)即单纯买入,然后由转移方程定义有\(f_{i,j}=......
  • CF1155D 题解
    题目传送门题目分析说实话,第一眼这题以为是贪心...(事实上我看所有动态规划都像贪心)。然后接着发现贪心明显做不了,又看见最大子段和,很容易联想到\(\text{dp}\)。在设计......
  • 牛客题解 贝伦卡斯泰露
    链接:https://ac.nowcoder.com/acm/problem/14132来源:牛客网题解作者岛田小雅子序列的概念,需要区别于子串。本来以为是道DP题,看了下范围发现爆搜好像问题也不是很大......
  • 线段树学习笔记(基础&进阶)(一) | P3372 【模板】线段树 1 题解
    什么是线段树线段树是一棵二叉树,每个结点存储需维护的信息,一般用于处理区间最值、区间和等问题。线段树的用处对编号连续的一些点进行修改或者统计操作,修改和统计的复杂......