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 }