• Codeforces Round #396 (Div. 2) C


    请点击我直往原题~ 

    题意:

    给一串字符串,再给每个小写字母能处在的子串最大长度(例如 len(a) == 3,那么包含字母a字符串最大长度为3),求三个问题:

    1.拆分方案数

    2.最长子串

    3.原串至少分成几部分

    题解:

    1.用dp1[i](1~n) 来维护到达第i个字符的最大方案数,dp2[i] 来维护最小拆分数。

    2.第一层循环:i从1走到n。

       第二层循环:j从字符的前一个i-1走到0。如果不满足check则跳出循环。

             代表将字符串 “最后一刀” 切到第j个字符:前j个一部分,剩下的一部分。当j==0时代表前i个字符只构成一个子串。

    3.check是检测一段子串能否满足条件:每个小写字母能处在的子串最大长度

    4.不难想到dp1[i] += dp1[j],代表  前j个的方案数(已知) &  剩下的字符串构成一个部分(check能否满足条件)

         dp2[i] = min(dp2[i], dp2[j] + 1) , 代表   维护 前j个的结果再+1(剩余字符构成一部分)的最小值

         ans = max(ans,i - j)  用 [j+1,i]这部分结果来维护 子串最大值

    5.但边界 j==0 要特殊判断,即前i个字符只构成一个子串。如果 j==0 时满足条件(check),则dp1[i] +=1 ,dp2[i] = 1;

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <bits/stdc++.h>
    using namespace std;
    const int MOD = 1e9 + 7;
    int n;
    char str[1010];
    int len[30];
    bool check(int low,int high)
    {
        for(int i = low; i <= high; i++)
            if(len[str[i] - 'a'] < high - low + 1)
                return false;
        return true;
    }
    int main()
    {
        scanf("%d",&n);
        scanf("%s",str+1);
        for(int i = 0; i < 26; i++)
            scanf("%d",len + i);
        int dp1[1010],dp2[1010],ans;
        memset(dp1,0,sizeof(dp1));
        memset(dp2,0x3f3f3f3f,sizeof(dp2));
        ans = 1;
        for(int i = 1; i <= n; i++)
        {
            for(int j = i - 1; j >= 0; j--)
            {
                if(j == 0 && check(1,i))
                    dp1[i]++,dp2[i] = 1;
                else if(!check(j + 1,i))
                    break;
                dp1[i] = (dp1[i] + dp1[j]) % MOD;
                dp2[i] = min(dp2[j] + 1,dp2[i]);
                ans = max(ans,i - j);
                //cout << i << ' ' << j << ' ' << dp1[i] << endl;
            }
        }
        cout << dp1[n] << endl;
        cout << ans << endl;
        cout << dp2[n] << endl;
    }
  • 相关阅读:
    吴恩达机器学习笔记 —— 19 应用举例:照片OCR(光学字符识别)
    吴恩达机器学习笔记 —— 17 推荐系统
    吴恩达机器学习笔记 —— 13 支持向量机
    吴恩达机器学习笔记 —— 15 降维
    SAP MM 无价值物料管理的一种实现思路
    第一节 电商
    e3mall_day09
    activemq整合spring的配置
    log4j简介
    ActiveMQ的入门使用
  • 原文地址:https://www.cnblogs.com/bestwzh/p/6388146.html
Copyright © 2020-2023  润新知