• PTA 团体程序设计天梯赛 L3-020 至多删三个字符


    $f[i][j]$表示到第$i$个字符,已经删去了$j$个字符的方案数。

    显然的转移:

    $f[i][j] = f[i - 1][j] + f[i - 1][j - 1]$

    但是这样会有重复,我们考虑什么情况会重复。

    比如说:'aabab'中的'bab',我们删去'ba',得到'aab',删去'ab'得到'aab',两者是相同的

    1 2 3 4 5

    a a b a b

    我们假设之前的每一位存的都是没有重复的方案数

    就刚才的情况,我们发现当我们递推到第$5$个位置的时候,删去第三位和第四位的'ba',但是保留着第五位的'b'

    那这种情况和递推到第$3$个位置的时候,保留着第$3$位的'd'是一样的

    即:

    $f[5][2] = f[2][0]$

    $f[5][3] = f[2][1]$

    减去这些重复情况,我们就能保证已经递推过来的情况中没有重复情况

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 1000010
     6 int n;
     7 char s[N];
     8 int pos[220];
     9 ll f[N][4];
    10 
    11 int main()
    12 {
    13     while (scanf("%s", s + 1) != EOF)
    14     {
    15         memset(pos, -1, sizeof pos);
    16         n = strlen(s + 1);
    17         f[0][0] = 1;
    18         for (int i = 1; i <= n; ++i)
    19         {
    20             int d = pos[s[i]];
    21             pos[s[i]] = i;
    22             f[i][0] = f[i][1] = 1;
    23             for (int j = 1; j < 4; ++j)
    24             {
    25                 f[i][j] += f[i - 1][j];
    26                 f[i][j + 1] = f[i - 1][j];
    27                 if (d != -1 && j - i + d >= 0)
    28                     f[i][j] -= f[d - 1][j - i + d];
    29             }
    30         }
    31         printf("%lld
    ", f[n][0] + f[n][1] + f[n][2] + f[n][3]);
    32     }
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    使用doctest单元测试方式培训讲解:Python字符串格式化(适合测试工程师的学习方法)
    树莓派Raspberry中成功安装RobotFramework+Selenium
    树莓派Raspberry实践笔记-安装使用minicom
    树莓派Raspberry实践笔记-解决官方文档打开慢问题
    window电脑蓝屏
    fastjson基本用法
    自定义注解
    curl工具
    观察者模式
    工厂模式
  • 原文地址:https://www.cnblogs.com/Dup4/p/10584694.html
Copyright © 2020-2023  润新知