zoukankan      html  css  js  c++  java
  • 牛客网 Wannafly挑战赛12 删除子串(线性dp)

    题目描述

    给你一个长度为n且由a和b组成的字符串,你可以删除其中任意的部分(可以不删),使得删除后的子串“变化”次数小于等于m次且最长。
    变化:如果a[i]!=a[i+1]则为一次变化。(且新的字符串的首字母必须是'a')
    如果初始串全为b,则输出0。

    输入描述:

    第一行输入两个数n,m。(1 <= n <= 105,0 <= m <= 10)
    第二行输入一行长度为n且由a和b组成的字符串

    输出描述:

    输出一个数字表示最长长度

    示例1

    输入

    8 2
    aabbabab

    输出

    6

    说明

    原串可以变成aabbbb,只改变了一次,且长度最长。

    题意

    如上

    题解

    一看到这题就是Dp题,从变化次数m切入

    这里j指变化次数,数组a是指最后放的是字符a的长度,b同理

    a[j]=max(a[j]+1,b[j-1]+1),s[i] = 'a'(1<=j<=m+1)

    b[j]=max(b[j]+1,a[j-1]+1),s[i] = 'b'

    上面的意思是,如果s[i] = ‘a’,a[j]直接加上去,或者由b[j-1]通过变化加上去

    这里由于新的字符串要求以‘a’开头,所以假设新串以‘b’通过变化得到为开始点

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int main()
     4 {
     5     int n,m,a[11],b[11];
     6     char s[100005];
     7     for(int i=0;i<=10;i++)
     8         a[i]=b[i]=-1e9;
     9     cin>>n>>m;
    10     m++;b[0]=0;
    11     scanf("%s",s+1);
    12     for(int i=1;i<=n;++i)
    13         for(int j=m;j;--j)
    14             if(s[i]=='a')
    15                 a[j]=max(a[j]+1,b[j-1]+1);
    16             else
    17                 b[j]=max(b[j]+1,a[j-1]+1);
    18     int ans=0;
    19     for(int i=m;i;--i)
    20         ans=max(ans,max(a[i],b[i]));
    21     cout<<ans;
    22     return 0;
    23 }
  • 相关阅读:
    基本数据类型与其包装类型
    String与常量池(JDK1.8)
    数据库知识归纳(面试向)
    HashMap、ConcurrentHashMap以及HashTable(面试向)
    Java多线程基础(面试向)
    Java的类加载
    Sql语句的一些事(二)
    RUBY惯用方法(转)
    Ruby中区分运行来源的方法(转)
    ruby安装devkit
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/8637047.html
Copyright © 2011-2022 走看看