http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2607
Mountain subsequences Time limit:1000ms Memory limit:65536k have questions? Dot here ^_^ Title Description
Coco is a beautiful acmer girl living in a very beautiful mountain. There is many trees and flowers on the mountain, and there is many animals and birds also. Coco like the mountain so much, she now name some letter sequences as Mountain subsequences.
A Mountain subsequence is defined as following:
1. If the length of the subsequence is N, there should are a max value letter, and the subsequence should like this, A1 < ; ...< ai < ai+1 < Amax > AJ > Aj+1 > ... > an
2. It should has at least 3 elements, and in the "left" of the max value letter there should has at least one element, the Same as in the right.
3. The value of the letter is the ASCII value.
Given a letter sequence, Coco wants to know how many Mountain subsequences exist.
inputInput contains multiple test cases.
There is a number n (1<= n <= 100000) which means the length of the letter sequence in the first line, And the next line contains the letter sequence.
Please note this letter sequence only contain lowercase letters.
OutputFor each case, please output the number of the Mountain subsequences module.Sample Input
4abca
Sample Output
4
TipsThe 4 mountain subsequences are:
ABA, ACA, BCA, ABCA
Source2013 ACM College Student Program Design contest in Shandong provinceSample Program
Analysis:
Here you are. A string of length n is composed only of lowercase English letters to satisfy
A1 < ...< AI < ai+1 < Amax > AJ > Aj+1 > ... > an
The number of substrings, in fact, is to count all satisfy with a certain element as the center of the left increment, the right to decrement the numbers of substrings, require the substring
The minimum length is 3, and the center element has at least one element around it.
The title tells us that the input string contains only 26 English letters, so we just enumerate each location and then record each position to the left to meet
The number of conditions, the right to meet the number of conditions, and finally multiply it up. The key is how do we count the number of left and right sides to meet?
The instinctive reaction tells me that I can do it with DP, mostly because there is the basis for the longest increment subsequence I've done before. But
The teacher told me that this is not called DP, see the code will find, in fact, is a recursive solution relationship. I always think that the reason I can think of
Here, it is entirely the idea of using DP's phase partitioning, whether or not. So, how to divide the stage? We define
Array Dp[26],dl[maxn],dr[maxn],dp[c] Indicates the number of satisfied cases ending with the character C, Dl[i] indicates that the left side of the first position satisfies
The number of conditions, Dr[i] indicates the number of conditions to be satisfied on the right side of the first position. Of course, we can find that dp[s[i]] = (Dl[i] + 1), s[i]= C;
1 means s[i] is satisfied by a single time, Dl[i] indicates that he satisfies the situation on the left side of the various situations plus s[i].
Attention:
A careful reunion asked, in a string if there is the same letter, then their DP value is the same? The answer is given in the test instructions.
The topic was used when the substring was requested.
A1 < ...< AI < ai+1 < Amax > AJ > Aj+1 > ... > an
Such a formula, each element represents a different position of the element, that is, in the string Aaba should have Aba,aba two answers,
And not just the ABA one. Since the first two substrings are the same in form, but correct in their nature, a and a are from different sources,
can be represented as A1BA and a2ba two answers.
AC Code:
1#include <iostream>2#include <cstring>3 #defineMAXN 1000054 #defineMoD 20125 using namespacestd;6 7 CharSTR[MAXN];8 intdp[ -],DL[MAXN],DR[MAXN],S[MAXN];9 intMain ()Ten { One intN; A while(cin>>N) - { -Cin>>str; the for(intI=0; i<n;i++) -s[i]=str[i]-'a'; -Memset (DP,0,sizeof(DP)); -memset (DL,0,sizeof(DL)); +memset (DR,0,sizeof(DR)); - for(intI=0; i<n;i++) + { A for(intj=0; j<s[i];j++) atDl[i]= (Dl[i]+dp[j])%MoD; -Dp[s[i]]= (dp[s[i]]+dl[i]+1)%MoD; - } -Memset (DP,0,sizeof(DP)); - for(inti=n-1; i>=0; i--) - { in for(intj=0; j<s[i];j++) -Dr[i]= (Dr[i]+dp[j])%MoD; toDp[s[i]]= (dp[s[i]]+dr[i]+1)%MoD; + } - intans=0; the for(intI=0; i<n;i++) *Ans= (Ans+dl[i]*dr[i])%MoD; $cout<<ans<<Endl;Panax Notoginseng } - return 0; the}
View Code
Official code:
1#include <iostream>2#include <cstdio>3#include <cstring>4 using namespacestd;5 Const intMAXN =100000+5;6 intN;7 CharS[MAXN];8 intDL[MAXN], DR[MAXN], dp[ -], cnt[ -];9 Const intMoD = -;Ten intMain () { OneFreopen ("data.in","R", stdin); AFreopen ("Data.out","W", stdout); - while(~SCANF ("%d", &N)) { -scanf"%s", s); the for(inti =0; I < n; i++) S[i]-='a'; -Memset (DP,0,sizeof(DP)); -memset (CNT,0,sizeof(CNT)); -memset (DL,0,sizeof(DL)); +memset (DR,0,sizeof(DR)); - for(inti =0; I < n; i++) { + for(intj =0; J < S[i]; J + +) { ADl[i] + = Dp[j] +Cnt[j]; atDl[i]%= -; - } -Cnt[s[i]] + +; -Cnt[s[i]]%= -; -Dp[s[i]] + =Dl[i]; -Dp[s[i]]%= -; in - } to +Memset (DP,0,sizeof(DP)); -memset (CNT,0,sizeof(CNT)); the * for(inti = n-1; I >=0; i-- ) { $ for(intj =0; J < S[i]; J + +) {Panax NotoginsengDr[i] + = Dp[j] +Cnt[j]; -Dr[i]%= -; the } +Cnt[s[i]] + +; ACnt[s[i]]%= -; theDp[s[i]] + =Dr[i]; +Dp[s[i]]%= -; - } $ intAns =0; $ for(inti =0; I < n; i++) { -Ans + = dl[i] *Dr[i]; -Ans%= -; the } -printf"%d\n", ans);Wuyi } the}
View Code
Sdutoj Mountain subsequences