Reverse and Compare(DP)

Reverse and Compare


Time limit : 2sec / Memory limit : 256MB

Score : 500 points

Problem Statement

You have a string A=A1A2…An consisting of lowercase English letters.

You can choose any two indices i and j such that 1≤ijn and reverse substring AiAi+1…Aj.

You can perform this operation at most once.

How many different strings can you obtain?

Constraints

  • 1≤|A|≤200,000
  • A consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

A

Output

Print the number of different strings you can obtain by reversing any substring in A at most once.


Sample Input 1

Copy
aatt

Sample Output 1

Copy
5

You can obtain aatt (don't do anything), atat (reverse A[2..3]), atta (reverse A[2..4]), ttaa (reverse A[1..4]) and taat (reverse A[1..3]).


Sample Input 2

Copy
xxxxxxxxxx

Sample Output 2

Copy
1

Whatever substring you reverse, you'll always get xxxxxxxxxx.


Sample Input 3

Copy
abracadabra

Sample Output 3

Copy
44


//很简单的一道DP,但是难想到,想到极其简单
dp[i]为前 i 个数的不同串数的话,dp[i] = dp[i-1] + sum[ str[j]!=str[i] ] (1<=j<i) (前面不等于字符 i 的所有字符的个数)
因为,只要不同,就能reverse[j,i]出一个新串,相同时,reverse[j+1,i-1]是和前相同的,算过了
此题,容易想到回文串什么的,回文串就是个坑,根本不对,跳进去就很难出来了
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 #define LL long long
 6 #define MX 200500
 7 
 8 LL dp[MX];
 9 LL num[26];
10 char s[MX];
11 
12 int main()
13 {
14     scanf("%s",s+1);
15     int len = strlen(s+1);
16     dp[0]=1;
17     for (int i=1;i<=len;i++)
18     {
19         dp[i]=dp[i-1];
20         for (int j=0;j<26;j++)
21         {
22             if (s[i]=='a'+j) continue;
23             dp[i] += num[j];
24         }
25         num[ s[i]-'a' ]++;
26     }
27     printf("%lld\n",dp[len]);
28     return 0;
29 }
View Code

 




posted @ 2017-08-27 08:12  happy_codes  阅读(289)  评论(2编辑  收藏  举报