1 条题解

  • 0
    @ 2025-8-24 22:24:48

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar ☯☯枫☯☯
    Why son code is not called daughter code?

    搬运于2025-08-24 22:24:48,当前版本为作者最后更新于2021-06-27 15:28:25,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目传送门

    更好的阅读体验

    实话说,别想太多,就能速切本题。

    算法分析:记忆化搜索

    第一眼看到可能会想到状压 dp,但事实上没那么复杂。如果要状压的话,状态数有 N×226=6710886400N\times 2^{26}=6710886400 种,显然在时空上均无法接受。

    考虑记忆化搜索。简单地,用 map 记录状态。由于顺序无关,每一轮搜索可以从上一轮之后开始。为了记忆化简单,我们可以把已经包含字符的状态压缩在 stasta 里,然后用 ffro,staf_{fro,sta} 表示到 frofro 时,使用状态为 stasta 的情况总数。然后搜索即可。

    下面说明记忆化搜索比状压 dp 优秀。

    状压 dp 虽然常数较小,但所有状态几乎是跑满的。由于仅有 2626 个字符,且一个单词很可能包含多种字符,因此在大多数情况下,很快就能组合成一个测试句且情况很容易重复。在已经成为测试句的情况下,剩余的单词选与不选均不会产生影响。记这时已经使用到第 frofro 个单词,那么可以直接返回 2nfro2^{n-fro} 作为答案。

    在最坏情况下,每一层只能获得一个新字符。由于单词长度较长(不超过 100100),因此这种情况很难出现。如果出现,可以加入特判剔除这种状况(然鹅本题中并没有这样恶心的数据)。

    需要注意的是,在 map 中进行查找时,最好不要直接将状态作为下标进行查找。因为在 map 的机制里,若找不到目标,将自动建立一个空值。而 map 的效率与其元素个数直接相关。这样做将大幅降低 map 的效率,且空间上也不能承受。

    下面给出代码:

    #include<bits/stdc++.h>
    #define reg register
    #define ll long long
    #define F(i,a,b) for(reg int i=a;i<=b;++i)
    using namespace std;
    inline int read();
    const int N=105,M=30,all=(1<<26)-1;
    int b[N],n;
    char c[N];
    ll ans,pww[M] {1};
    map<int,ll>f[M];
    ll dfs(int fro,int sta){
        if(sta==all)return pww[n-fro];
    	//直接计算得出
        if(f[fro].find(sta)!=f[fro].end())return f[fro][sta];
        //用 map.find 不会建立空值 
        ll ans=0;
        F(i,fro+1,n)ans+=dfs(i,sta|b[i]);
        f[fro][sta]=ans;//记忆化 
        return ans;
    }
    int main() {
        F(i,1,26)pww[i]=pww[i-1]<<1ll;
        n=read();
        F(i,1,n) {
            scanf("%s",c+1);
            int len=strlen(c+1);
            F(j,1,len)b[i]|=(1<<(c[j]-'a'));//状态压缩 
        }
        ans=dfs(0,0);
        printf("%lld",ans);
        return 0;
    }
    inline int read() {
        reg int x=0;
        reg char c=getchar();
        while(!isdigit(c))c=getchar();
        while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x;
    }
    

    AC

    欢迎讨论交流,请点个赞哦~

    • 1

    信息

    ID
    5607
    时间
    1000ms
    内存
    32MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者