zoukankan      html  css  js  c++  java
  • codeforces

    C. Mahmoud and a Message
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    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.

    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.

    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.

    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:

    • How many ways are there to split the string into substrings such that every substring fulfills the condition of the magical paper, the sum of their lengths is n and they don't overlap? Compute the answer modulo 109 + 7.
    • What is the maximum length of a substring that can appear in some valid splitting?
    • What is the minimum number of substrings the message can be spit in?

    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".

    Input

    The first line contains an integer n (1 ≤ n ≤ 103) denoting the length of the message.

    The second line contains the message s of length n that consists of lowercase English letters.

    The third line contains 26 integers a1, a2, ..., a26 (1 ≤ ax ≤ 103) — the maximum lengths of substring each letter can appear in.

    Output

    Print three lines.

    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.

    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.

    Examples
    Input
    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
    Output
    3
    2
    2
    Input
    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
    Output
    401
    4
    3
    Note

    题意:

    给定一个只含有小写字母的字符串以及每个字母能出现的次数。

    这个次数是这样规定的,在某个子串中如果含有某个字母的时候,那么这个子串的长度不能超过该字母规定的次数。

    现在求三个数:

    第一个,你可以随意分割字符串,求满足条件的分割方案总数。

    第二个,在这些子串中,最长的子串的长度是多少。

    第三个,最少能分割成几个子串。

    题解:

    分割总数显然可以求得,设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] << "
    " << maxn << "
    " << dp1[n] << endl;
    63     }
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    JS中的call、apply、bind 用法解疑
    style、currentStyle、getComputedStyle(不同浏览器获取css样式)区别介绍
    Ajax 整理总结(进阶)
    Ajax 整理总结(入门)
    js_面向对象编程
    李炎恢bootstarp_项目实战__瓢城企业(注释+源码)
    bootstrap学习笔记--bootstrap排版类的使用
    bootstrap学习笔记--bootstrap网格系统
    对mysql快速批量修改,查重
    MyISAM 和 InnoDB 的区别与优化
  • 原文地址:https://www.cnblogs.com/Jstyle-continue/p/6379708.html
Copyright © 2011-2022 走看看