• ABC214F substrings


    题目描述

    给定一个字符串

    给定一个字符串,求有多少没有连续字母出现不同子序列

    字符串长度为(2 imes 10^5)

    题解

    官方题解

    看起来像是dp题,于是列个式子

    我们先不考虑重复的问题

    (f[i])表示以i为结尾且字母(i)必须被选择的方案数

    (f[i]=sum f[j],1<=j<=i-1)

    接下来想如果出现重复字符怎么办

    我们发现,对于(s[i]=s[j]),即字符相等时,任何(j)以前的答案都无需再次统计

    因为我们可以认为用(i)​位置上的字符替换(j)​位置,则(f[j])​就包括从1到j的所有答案

    关于边界,f[0]=1

    加上一些其他的小判断即可,不知道为什么官方题解就没这么多事情qwq

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<cstring>
    using namespace std;
    const int inf=0x7fffffff;
    typedef long long ll;
    #define maxn 200009
    char s[maxn];
    int f[maxn];
    #define mod 1000000007
    signed main()
    {
    	scanf("%s",s+1);
    	int n=strlen(s+1);
    	f[1]=1,f[0]=1;
    	for(int i=1;i<=n;i++)
    	{
    		bool flag=0;
    		if(s[i]==s[i-1])flag=1;
    		if(s[i]==s[i-1]&&i-2==0)continue;//这个是前两个字符一样,第二个字符答案为0
    		for(int j=i-2;j>=0;j--)
    		{
    			f[i]=(f[j]+f[i])%mod;
    			if(s[i]==s[j]&&j==1)break;
    			if(s[i]==s[j+1]||flag)break;//如果连续两个一样,光统计上一个字符的前一位答案即可
    		}
    		//cout<<f[i]<<endl;
    	 } 
    	ll ans=0;
    	for(int i=1;i<=n;i++)ans=(ans+f[i])%mod;
    	printf("%lld
    ",ans%mod);
    	return 0;
    }
    
    
  • 相关阅读:
    为什么前后端分离了,你比从前更痛苦?
    HTML命名规范
    常用一屏自适应布局(一)
    CSS-网站导航栏标题之间的分隔符
    React-setState源码的理解
    如何在React-Native上使用Typescript
    immutable-js基础
    stylus 移动端边框1像素问题解决方案
    react native ts环境搭建
    react结合ts与mobx环境搭建步骤详解
  • 原文地址:https://www.cnblogs.com/lzy-blog/p/15143192.html
Copyright © 2020-2023  润新知