zoukankan      html  css  js  c++  java
  • CF578D LCS Again

    题目链接

    题意分析

    怎么说呢 感觉这道题还是找规律套结论

    首先 对于一个字符串 我们最直观的想法就是去掉一个字符 然后再在其余n个位置每个位置可以有m-1种字符插入

    那么就存在n*(m-1)种方案

    但是存在重复的

    1. 对于aaabbbccc这种存在一段连续相同字符的字符串 很显然 一段连续相同字符的话 我们只能算上一种

    2.我们考虑这样一种字符串abababababab

    abababababa_ → abababaababa_ → abababaababa
    abababa_abab → abababa_ababa → abababaababa
    
    abababababa_ → ababababbaba_ → ababababbaba
    abababab_bab → abababab_baba → ababababbaba
    

    对于一个长度为k的这样的字符串

    第2个字符存在1个子串 第3个字符存在2个子串 ... 第k个字符存在k-1个子串

    所以一共存在(frac{k(k-1)}{2})种重复情况

    所以我们需要把这些也去除掉

    CODE:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #define M 100080
    using namespace std;
    char s[M];
    int n,m;
    long long ans,k;
    int main()
    {
    	scanf("%d%d",&n,&m);
    	scanf("%s",s+1);
    	for(int i=1;i<=n;++i)
    	if(s[i]!=s[i-1]) ans+=(long long)n*(long long)(m-1);
    	k=1LL;
    	for(int i=2;i<=n;++i)
    	{
    		if(k==1)//这是起始的边界情况处理
    		{
    			if(s[i]!=s[i-1]) ++k;
    		}
    		else
    		{
    			if(s[i]==s[i-2]) ++k;//按照上述字符串的要求进行处理
    			else
    			{
    				ans-=k*(k-1)/2;
    				if(s[i]!=s[i-1]) k=2LL;//这是起始的边界情况
    				else k=1LL;
    			}
    		}
    	} 
    	ans-=k*(k-1)/2;
    	printf("%lld
    ",ans);
    	return 0;
    } 
    
  • 相关阅读:
    利用Express模拟web安全之---xss的攻与防
    JavaScript之引用类型
    JavaScript之变量、作用域和内存问题
    linux学习之缓存机制
    linux学习之vimrc配置推荐
    linux系统之free命令详解
    JavaScript之函数
    JavaScript之语句
    JavaScript之字符串、对象及操作符
    Navicat for MySQL 之数据库迁移
  • 原文地址:https://www.cnblogs.com/LovToLZX/p/14028443.html
Copyright © 2011-2022 走看看