原题: https://pintia.cn/problem-sets/994805046380707840/problems/994805046946938880
题意:
给出一个字符串,可以删除0~3个字符,问结果的可能种数。
解析:
很自然的想法,用 表示到了第i个位置,删除j个字符的可能性。显然有 。但是会有重复的情况,例如,删除一个字符时 会重复,删除两个时 会重复,三个时 会重复。
其他情况都可以归结为这三种,例如 虽然删除第一个a和第二个b会重复,但是可以看成前面两个a与后面两个b造成的影响。
假设i前面最多j的位置k有一个字符与第i个字符相同,那么 相当于多算了 。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
char x[1000009];
long long dp[1000009][4];
int main(){
scanf("%s",x+1);
int len=strlen(x+1);
for(int i=0;i<=len;i++)dp[i][0]=1;
for(int i=1;i<=len;i++){
for(int j=1;j<=min(3,i);j++){
dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
for(int k=i-1;i-k<=j&&k>0;k--){
if(x[k]==x[i]){
dp[i][j]-=dp[k-1][j-(i-k)];
break;
}
}
}
}
printf("%lld\n",dp[len][0]+dp[len][1]+dp[len][2]+dp[len][3]);
}