pta2018 L3-2 Delete up to three characters (30 points)

L3-2 Delete up to three characters ( 30 points)

Given a string consisting of all lowercase English letters, allowing you to delete at most 3 of them, how many different strings are possible as a result?

Input format:

The input is given in one line consisting of all lowercase English letters and the length is in the interval [4, 10

6

] inside the string.

Output format:

Print the number of distinct strings in a line with at most 3 characters removed.

Input sample:

ababcc

Sample output:

25

hint:

Delete 0 characters to get "ababcc" .

Delete 1 character to get "babcc", "aabcc", "abbcc", "abacc" and "ababc" .

Delete 2 characters to get "abcc", "bbcc", "bacc", "babc", "aacc", "aabc", "abbc", "abac" and "abab" .

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



dp[i][j] (i represents the length of the string, j represents the number of digits to delete)


Pushable dp[i][j]=dp[i-1][j-1]+dp[i-1][j]

Because the added one is either deleted or still kept



What is now obtained is the recursive formula of general strings, such as abcde

There are also special ones to deal with, such as abab, aaaaa, etc.

Then some special conditions are needed to satisfy



If there is an adjacent XX like this:

                   1. Then dp[i][1]=dp[i-1][1] (the number of deleted bits has not changed)

                  2. Then the number of deleted two bits is reduced by dp[i-2][1] than normal; because the deletion of the first X and the deletion of the second X are repeated, so one dp[i-2][1 is subtracted ] (one of the first i-2 is deleted)

                  3.那么删三位的数量要比正常的减少dp[i-2][2];因为删第一个X和删第                        个X重复,所以要减去一个dp[i-2][2](前面i-2个中有两个被删)



如果出现了X_X这样相邻的:(注意,不包括XXX这种情况)

                        1.删一位不用处理,与一般相同

                   2.删两位只会在删X_和删_X时相同,所以减1即可

                    3.删三位其实就是删_X_和删_ _X时重复,所以减去dp[i-3][1]即可



如果出现了X_X这样相邻的:(注意,不包括XXXX,XX_X,X_XX这几种情况)

                    

                      1.删一位不用处理,与一般的相同

                       2.删两位不用处理,与一般的相同

                        3.删三位其实就是删X_ _和删_ _X时重复,所以减去1即可


#include<iostream>
using namespace std;
long long dp[1000005][4];
int main(){
    string ss;
    cin>>ss;
    dp[1][0]=dp[1][1]=1;
    dp[0][2]=dp[0][3]=0;
    int n=int(ss.size());
    for(int i=2;i<=n;i++){
        dp[i][0]=1;
        for(int j=1;j<=3;j++){
            dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
            if(ss[i-1]==ss[i-2]&&j==1) dp[i][j]-=1;
            else if(ss[i-1]==ss[i-2]&&j==2) dp[i][j]-=dp[i-2][1];
            else if(ss[i-1]==ss[i-2]&&j==3) dp[i][j]-=dp[i-2][2];
            
            if(i>=3&&ss[i-1]==ss[i-3]&&ss[i-1]!=ss[i-2]&&j==2) dp[i][j]-=1;
            else if(i>=3&&ss[i-1]==ss[i-3]&&ss[i-1]!=ss[i-2]&&j==3) dp[i][j]-=dp[i-3][1];
            
            if(i>=4&&ss[i-1]==ss[i-4]&&ss[i-1]!=ss[i-2]&&ss[i-1]!=ss[i-3]&&j==3) dp[i][j]-=1;
            
           //printf("%lld ",dp[i][j]);
        }
        //printf("\n");
    }
    cout<<dp[n][0]+dp[n][1]+dp[n][2]+dp[n][3]<<endl;
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325524600&siteId=291194637