zoukankan      html  css  js  c++  java
  • CF1131E String Multiplication 题解

    关于发现调了两个小时的题被学长场切了

    一些结论

    翻一下题面给出的“乘法”,其实就是把一个字符串重复插入到另一个字符串中
    首先可以发现,除了 (p_n) ,其他字符串至多只有1的权值,所以我们先考虑 (p_n)
    可以想到,相乘只会让字符串前缀权值或者后缀权值变大,也就是说相乘后会有变化的地方只有前缀和后缀
    进一步可以想到,如果该字符串并非整个串都是同一个字符,那么该字符串首位相连之后就不会再变化了
    所以考虑整个字符串字符相同的时候,就直接把 (p_n) 按题意乘到 (p_{n-1}) 里面,再按一般的方法处理
    注:图片中从上到下插入,根据题意实际上是从下到上乘
    IGuGSP.png

    做法

    • 倒序考虑这个式子,首先处理 (p_n)
    • 如果这个字符串并不是整个串都相等的,就考虑直接在其中找一个合法子序列
    • 然后考虑前后缀,如果前后缀是同一个字符,那么就在前面的字符串中找到一个一样的字符,用来把前后缀接在一起,前后缀不相同时也是一样
    • 如果整个串都相同,那么就把它和上一个串合并(因为如果整个串都相同,其实这个串性质和一个字符差不多)
    • 而对于递归到的串,也和上面的法则一样处理——连接前后缀、合并,用一个简单的乘法原理就能统计答案了
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #define ll long long
    using namespace std;
    char c[100001];
    vector<char>ch[100100];
    ll n,len,a[100001],ans(1),m;
    bool pool[100001][30];
    
    void dfs(ll dep,char sam=''){
        if(dep<1)return ;
        ll g=ch[dep].size();
        for(ll i=1;i<=g;i++)a[i]=0;
        for(ll i=0;i<=ch[dep].size();i++)c[i+1]=ch[dep][i];
        for(ll i=1;i<=g;i++){
            if(sam==''||c[i]==sam){
                ll j=i;
                for("lmh qs rrd";j<=g;j++)
                    if(c[i]!=c[j])break;
                j--;
                for(ll k=i;k<=j;k++)a[k]=j-i+1;
                ans=max(ans,(j-i+1)+len*(j-i+2));
                i=j;
            }
        }
        if(sam=='')sam=c[1];
        if(a[1]!=g){
            if(c[1]==c[g]){
                // ans=max(ans,(a[1]+a[g])+(a[1]+a[g]+2)*len);
                for(ll i=1;i<dep;i++)
                    for(ll j=0;j<=ch[i].size();j++)
                        if(ch[i][j]==sam)ans=max((a[1]+a[g])+(a[1]+a[g]+2)*len+1,ans);
            }
            else {
                for(ll i=1;i<dep;i++)
                    for(ll j=0;j<=ch[i].size();j++)
                        if(ch[i][j]==sam)ans=max(ans,1+(a[1]+1)*len+a[1]);
                for(ll i=1;i<dep;i++)
                    for(ll j=0;j<=ch[i].size();j++)
                        if(ch[i][j]==sam)ans=max(ans,1+a[g]+(a[g]+1)*len);
            }
        }
        else {
            len=g+(g+1)*len;
            dfs(dep-1,c[1]);
        }
    }
    
    int main(){
        scanf("%lld",&n);
        for(ll i=1;i<=n;i++){
            cin>>c+1;
            m=strlen(c+1);
            for(ll j=1;j<=m;j++)
                ch[i].push_back(c[j]);
        }
        dfs(n);
        cout<<ans;
        return 0;
    }
    
  • 相关阅读:
    MyISAM 和 InnoDB 索引的区别
    iOS crash日志
    。。。
    redis的缓存测试
    job测试
    笔记
    Android获取启动页面Activity方法
    UI自动化框架-一个小demo
    mitmproxy-java 的尝试
    monkey
  • 原文地址:https://www.cnblogs.com/caijiLYC/p/15525078.html
Copyright © 2011-2022 走看看