Mahmoud wrote a message s of length n. He wants to send it as a birthday present to his friend Moaz who likes strings. He wrote it on a magical paper but he was surprised because some characters disappeared while writing the string. That's because this magical paper doesn't allow character number i in the English alphabet to be written on it in a string of length more than ai. For example, if a1 = 2 he can't write character 'a' on this paper in a string of length 3 or more. String "aa" is allowed while string "aaa" is not.ios
Mahmoud decided to split the message into some non-empty substrings so that he can write every substring on an independent magical paper and fulfill the condition. The sum of their lengths should be n and they shouldn't overlap. For example, if a1 = 2 and he wants to send string "aaa", he can split it into "a" and "aa" and use 2 magical papers, or into "a", "a" and "a" and use 3 magical papers. He can't split it into "aa" and "aa" because the sum of their lengths is greater than n. He can split the message into single string if it fulfills the conditions.app
A substring of string s is a string that consists of some consecutive characters from string s, strings "ab", "abc" and "b" are substrings of string "abc", while strings "acb" and "ac" are not. Any string is a substring of itself.ide
While Mahmoud was thinking of how to split the message, Ehab told him that there are many ways to split it. After that Mahmoud asked you three questions:this
Two ways are considered different, if the sets of split positions differ. For example, splitting "aa|a" and "a|aa" are considered different splittings of message "aaa".spa
The first line contains an integer n (1 ≤ n ≤ 103) denoting the length of the message.3d
The second line contains the message s of length n that consists of lowercase English letters.code
The third line contains 26 integers a1, a2, ..., a26 (1 ≤ ax ≤ 103) — the maximum lengths of substring each letter can appear in.blog
Print three lines.three
In the first line print the number of ways to split the message into substrings and fulfill the conditions mentioned in the problem modulo 109 + 7.ci
In the second line print the length of the longest substring over all the ways.
In the third line print the minimum number of substrings over all the ways.
3
aab
2 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
3
2
2
10
abcdeabcde
5 5 5 5 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
401
4
3
題意:
給定一個只含有小寫字母的字符串以及每一個字母能出現的次數。
這個次數是這樣規定的,在某個子串中若是含有某個字母的時候,那麼這個子串的長度不能超過該字母規定的次數。
如今求三個數:
第一個,你能夠隨意分割字符串,求知足條件的分割方案總數。
第二個,在這些子串中,最長的子串的長度是多少。
第三個,最少能分割成幾個子串。
題解:
分割總數顯然能夠求得,設dp[i]爲前i個字符能分割的總數,則 dp[i] = ∑ dp[j], (j <= i, j ~ i 這一段知足次數的要求);
那麼顯然在dp的時候咱們更新最長的子串長度,若是dp[j-1]能夠分割的話,那麼能夠更新 maxn = max(maxn, i-j+1);
求最少的子串個數也能夠用dp,設 dp1[i]爲前i位中能分割的最少的字符串的個數,則 dp1[i] = min(dp1[i], dp1[j]+1), (j <= i, j~i 知足次數要求)
代碼:
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <bitset> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <cmath> 10 #include <list> 11 #include <set> 12 #include <map> 13 #define rep(i,a,b) for(int i = a;i <= b;++ i) 14 #define per(i,a,b) for(int i = a;i >= b;-- i) 15 #define mem(a,b) memset((a),(b),sizeof((a))) 16 #define FIN freopen("in.txt","r",stdin) 17 #define FOUT freopen("out.txt","w",stdout) 18 #define IO ios_base::sync_with_stdio(0),cin.tie(0) 19 #define mid ((l+r)>>1) 20 #define ls (id<<1) 21 #define rs ((id<<1)|1) 22 #define N 1005 23 #define INF 0x3f3f3f3f 24 #define INFF ((1LL<<62)-1) 25 using namespace std; 26 typedef long long LL; 27 typedef pair<int, int> PIR; 28 const int mod = 1e9+7; 29 30 int n, x, lim[30], dp[N], dp1[N]; 31 string s; 32 33 bool judge(int l, int r){ 34 int len = r-l; 35 rep(i, l, r){ 36 if(lim[s[i-1]-'a'] <= len) return false; 37 } 38 return true; 39 } 40 int main() 41 {IO; 42 //FIN; 43 while(cin >> n){ 44 cin >> s; 45 rep(i, 0, 25) { cin >> x; lim[i] = x; } 46 47 mem(dp, 0); 48 mem(dp1, INF); 49 dp1[0] = 0; 50 dp[0] = 1; 51 int maxn = 0, minn = n; 52 rep(i, 1, n){ 53 rep(j, 1, i){ 54 if(judge(j, i)){ 55 dp[i] = (dp[i]%mod+dp[j-1]%mod)%mod; 56 dp1[i] = min(dp1[i], dp1[j-1]+1); 57 if(dp[j-1]) 58 maxn = max(maxn, i-j+1); 59 } 60 } 61 } 62 cout << dp[n] << "\n" << maxn << "\n" << dp1[n] << endl; 63 } 64 return 0; 65 }