• Codeforces Round #349 (Div. 2) C. Reberland Linguistics DP


    题意:
    自己读了半天题,果断没看懂题意,看了题解才明白是这个意思啊。

    给一个字符串,去掉一个长度至少为5的前缀,剩下的切成长度为2或者3的串,且相邻的串不相同,问,最后可以切成多少个串且分别是什么;

    思路:

    dp[i][2]==1表示i,i+1形成的串可以满足要求,dp[i][3]==1同理;再就是转移了;

    考虑i位置,长度为2;

    (1)如果(i,i+1)与(i+2,i+3)相同,那么只有dp[i+2][3]==1时dp[i][2]=1;

    如果(i,i+1)与(i+2,i+3)不同,那么只要dp[i+2][2]==1或者dp[i+2][3]==1时dp[i][2]=1;

    (2)如果(i,i+1,i+2)与(i+3,i+4,i+5)相同,只有dp[i+3][2]==1时dp[i][3]=1;

    如果不同,那么只要dp[i+3][2]==1或者dp[i+3][3]==1时dp[i][3]=1;

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<vector>
    using namespace std;
    const int N=1e5+5;
    bool d[N][4];
    int main()
    {
        string s;
        cin>>s;
        if(s.size()<=6){
            printf("0
    ");return 0;
        }
        int n=s.size();
        d[n][2]=d[n][3]=1;
        vector<string>ans;
        for(int i=n-2;i>=5;i--){
            string now(s,i,2);
            string next(s,i+2,2);
            d[i][2]=(now!=next)&&d[i+2][2];
            d[i][2]=d[i][2]||d[i+2][3];
            if(d[i][2])ans.push_back(now);
            if(i==n-2)continue;
            string now1(s,i,3);
            string next1(s,i+3,3);
            d[i][3]=(now1!=next1)&&d[i+3][3];
            d[i][3]=d[i][3]||d[i+3][2];
            if(d[i][3])ans.push_back(now1);
        }
        sort(ans.begin(),ans.end());
        int sum=0;
        ans.push_back("");
        for(int i=0;i<ans.size()-1;i++)
            if(ans[i]!=ans[i+1])sum++;
        cout<<sum<<"
    ";
        for(int i=0;i<ans.size()-1;i++)
            if(ans[i]!=ans[i+1])cout<<ans[i]<<"
    ";
        return 0;
    }
  • 相关阅读:
    android kl文件
    ELF文件结构描述
    jquery开头
    win7无声音显示“未插入扬声器或耳机” 怎么解决
    xhtml头文件设置
    break和continue的区别
    php目录函数
    mysql语法
    php中怎么导入自己写的类
    截取文件后缀名
  • 原文地址:https://www.cnblogs.com/01world/p/5651220.html
Copyright © 2020-2023  润新知