• 51nod 1526 分配笔名(字典树+贪心)


    题意:

    班里有n个同学。老师为他们选了n个笔名。现在要把这些笔名分配给每一个同学,每一个同学分配到一个笔名,每一个笔名必须分配给某个同学。现在定义笔名和真名之间的相关度是他们之间的最长公共前缀。设笔名为a,真名为b,则他们之间的相关度为lcp(a,b)。那么我们就可以得到匹配的质量是每一个同学笔名和真名之间相关度的和。

    现在要求分配笔名,使得匹配质量最大。

    题解:

    对于真名建立一个字典树,然后每个笔名在字典树上打一个标记

    然后就变成了贪心,每个点的标记看是否能被字典树上的单词消掉,不能消,就让标记往上走即可。

    这里。。有一组深度特别深的数据

    dfs会内存超限,所以加了个特判(实际上。。应该用非递归的形式写比较好)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    const int maxn = 8e5 + 1;
    int trans[maxn][26], v[maxn], lab[maxn];
    int tot;
    long long ans;
    void Insert(char *S){
        int n = strlen(S), x = 0;
        for(int i = 0; i < n; i++){
            int ch = S[i] - 'a';
            if(trans[x][ch] == 0) trans[x][ch] = ++tot;
            x = trans[x][ch];
        }
        v[x]++;
    }
    
    void Change(char *S){
        int n = strlen(S), x = 0;
        for(int i = 0; i < n; i++){
            int ch = S[i] - 'a';
            if(trans[x][ch] == 0) break;
            x = trans[x][ch];
        }
        lab[x]++;
    }
    
    void dfs(int x, int d){
        if(d >= 5e5) { cout<<1<<endl; exit(0);}
        for(int i = 0; i < 26; i++){
            int to = trans[x][i];
            if(to == 0) continue;
            dfs(to, d+1);
            v[x] += v[to];
            lab[x] += lab[to];
        }
        if(v[x] >= lab[x]){
            ans += d*lab[x];
            v[x] -= lab[x];
            lab[x] = 0;
        } else {
            ans += d*v[x];
            lab[x] -= v[x];
            v[x] = 0;
        }
    }
    int n;
    char str[maxn];
    
    int main()
    {
        cin>>n;
        for(int i = 1; i <= n; i++){
            scanf("%s", str);
            Insert(str);
        }
        for(int i = 1; i <= n; i++){
            scanf("%s", str);
            Change(str);
        }
        dfs(0, 0);
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    随机性的控制
    856. 括号的分数
    376. 摆动序列(贪心算法)
    XGBoost 安装方法
    1405. 最长快乐字符串(贪心算法)
    1296. 划分数组为连续数字的集合(贪心算法)
    1353. 最多可以参加的会议数目(贪心算法)
    435. 无重叠区间(贪心算法)
    Array-数组-数据结构
    认识Redis和安装
  • 原文地址:https://www.cnblogs.com/Saurus/p/7638499.html
Copyright © 2020-2023  润新知