首页 > 其他分享 >[ABC343G] Compress Strings

[ABC343G] Compress Strings

时间:2024-04-24 16:24:48浏览次数:16  
标签:tmp int Compress vector 字符串 长度 ABC343G Strings size

题目链接:https://www.luogu.com.cn/problem/AT_abc343_g

solution:
1.首先我们将给出的字符串中互相包含的消去,可以使用kmp求前后缀来完成。和这道题的写法一样https://www.luogu.com.cn/problem/CF1200E
2.我们发现给出的字符串最多只有20个,考虑状压来求解所有可能
3.我们注意到这道题只需要求出最小的长度即可,那么转移的代价就是后面拼接上去的字符串的有效长度。何为有效长度:因为两个字符串相接,有可能在前一个串的后缀和后一个串的前缀会出现重叠,有效长度就是后一个串的长度减去重复的这部分得到的长度。
4.开始转移 我们设dp[state][j] state为当前的选中的字符串(目前得到的母串)构成的集合,j是当前的母串以第 j 个字符串结尾 ,如此得到的母串长度。
5.转移,具体操作见代码。


vector<int> kmp(string s)
{
    int n=s.size();
    vector<int> nxt(n+1);
    for(int i=1,j=0;i<n;i++)
    {
        while(j&&s[i]!=s[j])
        {
            j=nxt[j];
        }
        j+=(s[i]==s[j]);
        nxt[i+1]=j;
    }
    return nxt;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    vector<string> S(n);
    for(int i=0;i<n;i++)
    {
        cin>>S[i];
    }
    vector<string> tmp;
    sort(all(S),[&](string a,string b){
        return a.size()<b.size();
    });
    for(int i=0;i<n;i++)
    {
        int flag=1;
        for(int j=i+1;j<n;j++)
        {
            vector<int> f=kmp(S[i]+'#'+S[j]);
            if(find(all(f),S[i].size())!=f.end())
            {
                flag=0;
                break;
            }
        }
        if(flag)
        {
            tmp.push_back(S[i]);
        }
    }
    n=tmp.size();
    S=tmp;
    vector cost(n,vector<int> (n));
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(i==j) continue;
            vector<int> f=kmp(S[j]+'#'+S[i]);
            cost[i][j]=S[j].size()-f.back();
        }
    }
    vector dp((1<<n),vector<int> (n,1e9));
    vector<string> res(1<<n);
    for(int i=0;i<n;i++)
    {
        dp[1<<i][i]=S[i].size();
    }
    for(int s=1;s<(1<<n);s++)
    {
        for(int i=0;i<n;i++)
        {
            if(s>>i&1)
            {
                for(int j=0;j<n;j++)
                {
                    if(!(s>>j&1))
                    {
                        dp[s|1<<j][j]=min(dp[s|1<<j][j],dp[s][i]+cost[i][j]);
                    }
                }
            }
        }
    }
    int ans=*min_element(dp.back().begin(),dp.back().end());
    cout<<ans<<'\n';
}

标签:tmp,int,Compress,vector,字符串,长度,ABC343G,Strings,size
From: https://www.cnblogs.com/captainfly/p/18155713

相关文章

  • [题解][2021-2022年度国际大学生程序设计竞赛第10届陕西省程序设计竞赛] Type The Str
    题目描述给定n个字符串,有以下几种操作:打出一个字符,花费1。删除一个字符,花费1。复制并打出一个之前打出过的字符串,花费k。求打出所有n个字符串的最小花费。(注意,打出顺序和字符串输入的顺序不必相同)题解显然,操作3需要算字符串的最长公共子序列来处理。这个问题可以转换为......
  • 字符串占位符替换——StringSubstitutor
    1背景众所周知Java中的字符串占位符替换非常不友好,无论是String#format还是MessageFormat#format都只能说能用,但说不上好用,关于以上两种字符串格式化的用法请参考:JavaStringformat和MessageFormatformat,本文推荐org.apache.commons.text.StringSubstitutor,StrSubstitutor是......
  • CF1200E Compress Words 题解
    题目链接:CF或者洛谷注意到总字符串长度不超过\(1e6\),对于两个串之间找前后缀匹配,只要能暴力枚举长度,\(check\为\O(1)\),那么最后显然线性复杂度。可以考虑\(kmp\),也可以考虑字符串哈希,最好上双哈希,然后拼串显然是在尾部继续添加新的前缀哈希,这个需要添加的串可以单独由匹配......
  • 攻防世界no-strings-attached做法(简易版)
    首先查个壳,发现没壳,是32bit,那就丢进ida32中进行反编译进入main函数查看,里面有很多个函数,挨个点进去看看,找找关键点进入最后一个函数,发现了些东西,两个函数输出success和denied,if括号内的条件就得为非0,也就是说ws数组和s2数组相等才行,上面对s2数组进行了处理,那就直接看他咋处理的......
  • codeforces div4 Double Strings
    #include<iostream>#include<algorithm>#include<cstring>#include<map>usingnamespacestd;intT,n;strings[900005];map<string,int>mm;//存放每一个字符串是否出现过intmain(){ cin>>T; while(T--){ mm.clear();//每次清空mm里面的数......
  • [ARC058F] Iroha Loves Strings
    题意给定\(n\)个字符串\(s_1,s_2,...,s_n\)。你需要在其中选择一些字符串,按照顺序拼接。在所有生成的长度为\(k\)的字符串中,选择字典序最小的一个。\(n\le2000,k\le10^4,\sum|s_i|\le10^6\)Sol考虑一个朴素的dp。设\(f_{i,j}\)表示前\(i\)个字......
  • H. Impartial Strings
    H.ImpartialStringsProblem-H-Codeforces抽象场不传题解......
  • Channel-Wise Autoregressive Entropy Models For Learned Image Compression
    目录简介创新点模型框架信道条件熵模型实验&结果简介熵约束自动编码器的熵模型同时使用前向适应和后向适应。前向自适应利用边信息,可以被有效加入到深度网络中。后向自适应通常基于每个符号的因果上下文进行预测,这需要串行处理,这妨碍了GPU/TPU的有效利用。创新点本文引......
  • CF1930D1 - Sum over all Substrings (Easy Version)
    对于每一个\(f(i,j)\),我们考虑如何计算。我们发现,\(\texttt{1010}\)式的字符串很有用,所以这启发我们如果遇到了一个模式\(p_i=\texttt{'1'}\),那么我们可以在\(i+1\)的位置放一个\(\texttt{'1'}\)。这样我们直接处理了\(i,i+1,i+2\)。容易证明这是最优的。#incl......
  • [npm] npm打包/运行时,报:"95% emitting CompressionPlugin ERROR Error: error:030801
    1问题描述环境信息windows10node:v20.11.1>node--versionv20.11.1vue:2.6.12[dependencies]"vue":"2.6.12""vue-count-to":"1.0.13""vue-cropper":"0.5.5""vue-meta":&q......