给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串?

输入格式:

输入在一行中给出全部由小写英文字母组成的、长度在区间 [4, 1] 内的字符串。

输出格式:

在一行中输出至多删掉其中 3 个字符后不同字符串的个数。

输入样例:

ababcc

输出样例:

25

提示:

删掉 0 个字符得到 "ababcc"。

删掉 1 个字符得到 "babcc", "aabcc", "abbcc", "abacc" 和 "ababc"。

删掉 2 个字符得到 "abcc", "bbcc", "bacc", "babc", "aacc", "aabc", "abbc", "abac" 和 "abab"。

删掉 3 个字符得到 "abc", "bcc", "acc", "bbc", "bac", "bab", "aac", "aab", "abb" 和 "aba"。

显然这道题用动态规划状态转移,无奈动态规划学的很渣,重复情况需要考虑。

最基本的是到了第i位,删或者不删,不删表示删除个数不变,删了表示删除个数加1,以第i - 1个字符的情况为基础,创建数组dp[MAX][4],dp[i][j]表示到了第i(i >= 1)个字符,已经删了j个字符有多少字符串,我们要计算dp[i][j],考虑两种情况删或者不删,删的话,就是dp[i - 1][j - 1],表示在i - 1时删了j - 1,到了i后又删了一个一共删了j个,不删的话就是dp[i - 1][j],表示在第i - 1时就删了j个,第i个不删所以一共还是删了j个,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

但是肯定会有重复的情况,我们只需要保证,到了位置i我们清除掉他的重复情况,这样在计算后面情况时就不用考虑太多因为前面的都是没有重复的情况,要去掉重复的,只需要以前面的为基础即可。

比如  abcdedc,显然如果删除了de和ed是一样的,都生成abcc,我们从前往后计算,到了位置6(下标从1开始),我们按照上面的式子算出了它的情况,其中dp[6][2]会包含删除ed的情况,dp[6][3]也包含删除ed但不是ded的情况即在123位置中再选一个删除,对于dp[6][2]我们需要减去什么,显然现在是删除了两个字符,删除de的情况其实就是abc一个都不删除的情况,即dp[3][0],对于dp[6][3]删除了三个字符,包含ed且不是ded也就是要减去123位置有一个字符被删除了的情况,即dp[3][1],所以对于dp[i][j],我们需要记录s[i]上一次出现的位置d d = pos[s[i]],如果d不为0,而且j - (i - d) >= 0(i - d表示什么,比如上例中ed是两个字符,i - d = 2,j减去它表示到了位置d - 1,删了几个字符),那么就dp[i][j] -= dp[d - 1][j - i + d].

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 1000000
using namespace std;
typedef long long ll;
char s[MAX + ];
ll dp[MAX + ][];
int pos[];
int main() {
scanf("%s",s + );
dp[][] = ;
int len = strlen(s + );
for(int i = ;i <= len;i ++) {
dp[i][] = ;
int d = pos[s[i] - 'a'];
pos[s[i] - 'a'] = i;
for(int j = ;j < ;j ++) {
dp[i][j] += dp[i - ][j - ] + dp[i - ][j];
if(d && j - i + d >= ) {
dp[i][j] -= dp[d - ][j - i + d];
}
}
}
printf("%lld",dp[len][] + dp[len][] + dp[len][] + dp[len][]);
}

L3-020 至多删三个字符 (30 分)的更多相关文章

  1. L3-020 至多删三个字符 (30 分)(DP)

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805046946938880 学习地址: 2018CCCC-L3 ...

  2. pta l3-20(至多删三个字符)

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805046946938880 题意:给定一个长度<=106 ...

  3. L3-020 至多删三个字符 (30 分) 线性dp

    给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串? 输入格式: 输入在一行中给出全部由小写英文字母组成的.长度在区间 [4, 1] 内的字符串. 输 ...

  4. PAT L3-020 至多删三个字符

    https://pintia.cn/problem-sets/994805046380707840/problems/994805046946938880 给定一个全部由小写英文字母组成的字符串,允许 ...

  5. PTA L3-020 至多删三个字符 (序列dp/序列自动机)

    给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串? 输入格式: 输入在一行中给出全部由小写英文字母组成的.长度在区间 [4, 1] 内的字符串. 输 ...

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

    $f[i][j]$表示到第$i$个字符,已经删去了$j$个字符的方案数. 显然的转移: $f[i][j] = f[i - 1][j] + f[i - 1][j - 1]$ 但是这样会有重复,我们考虑什 ...

  7. [leetcode]680. Valid Palindrome II有效回文II(可至多删一原字符)

    Given a non-empty string s, you may delete at most one character. Judge whether you can make it a pa ...

  8. PTA 最多删除3个字符(DP) - 30分

    给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串? 输入格式: 输入在一行中给出全部由小写英文字母组成的.长度在区间 [4, 1] 内的字符串. 输 ...

  9. windows自带记事本导致文本文件(UTF-8编码)开头三个字符乱码问题

    在windows平台下,使用系统的记事本以UTF-8编码格式存储了一个文本文件,但是由于Microsoft开发记事本的团队使用了一个非常怪异的行为来保存UTF-8编码的文件,它们自作聪明地在每个文件开 ...

随机推荐

  1. Unity 如何在打包的时候执行一些逻辑

    1.如果想让unity在打包的过程中,执行一些逻辑,那么该如何做呢?代码如下: using UnityEditor; using UnityEditor.Build; using UnityEngin ...

  2. ASP.NET调用dos命令获取交换机流量

    protected void btn_Cisco_Click(object sender, EventArgs e) { try { string ip = txt_ip.Value; string ...

  3. DZY Loves Colors CodeForces - 444C (线段树势能分析)

    大意:有$n$个格子, 初始$i$位置的颜色为$i$, 美丽值为0, 有两种操作 将区间$[l,r]$内的元素全部改为$x$, 每个元素的美丽值增加$|x-y|$, $y$为未改动时的值 询问区间$[ ...

  4. Docker 构建 redis 集群

    安装docker 1.yum install docker 方法一: 1. docker pull redis 2.docker run -d --name redis-1 -p 7001:6379 ...

  5. Android将view保存为图片并放在相册中

    在Android中,可以将view保存为图片并放在相册中,步骤为 view->bitmap->file,即先将view转化为bitmap,再将bitmap保存到相册中. 需要将红框标注的v ...

  6. eclipse设置条件断点

    1. 在Breakpoints页面,选中断点然后右键,选择"Breakpoint Properties" 2. 勾选Conditional,并输入条件.这样,当name等于&quo ...

  7. dubbo的超时重试

    dubbo的超时分为服务端超时 SERVER_TIMEOUT 和客户端超时 CLIENT_TIMEOUT.本文讨论服务端超时的情形: 超时:consumer发送调用请求后,等待服务端的响应,若超过ti ...

  8. $digest already in progress 解决办法——续

    什么时候手动调用$apply()方法? 如果AngularJS总是将我们的代码wrap到一个function中并传入$apply(),以此来开始一轮$digest循环,那么什么时候才需要我们手动地调用 ...

  9. 等待进程结束wait,waitpid

    当子进程先于父进程退出时,如果父进程没有调用wait和waitpid函数,子进程就会进入僵死状态. pid_t wait(int *status); pid_t waitpid(pid_t pid, ...

  10. Python - Learn Note (3)

    Python之模块 包就是文件夹:包可以有多级: 模块就是 xxx.py文件:可以创建自己的模块,并且导入它们,模块的名字就和文件的名字相同: Python使用import语句导入一个模块. impo ...