zoukankan      html  css  js  c++  java
  • bzoj4567 背单词

    Description

    Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”。这时候睿智
    的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计划册是长这样的:
    —————
    序号  单词
    —————
     1
     2
    ……
    n-2
    n-1
     n
    —————
     
    然后凤老师告诉 Lweb ,我知道你要学习的单词总共有 n 个,现在我们从上往下完成计划表,对于一个序号为 x 
    的单词(序号 1...x-1 都已经被填入):
    1) 如果存在一个单词是它的后缀,并且当前没有被填入表内,那他需要吃 n×n 颗泡椒才能学会;
    2) 当它的所有后缀都被填入表内的情况下,如果在 1...x-1 的位置上的单词都不是它的后缀,那么你吃 x 颗泡
    椒就能记住它;
    3) 当它的所有后缀都被填入表内的情况下,如果 1...x-1的位置上存在是它后缀的单词,所有是它后缀的单词中
    ,序号最大为 y ,那么你只要吃 x-y 颗泡椒就能把它记住。
    Lweb 是一个吃到辣辣的东西会暴走的奇怪小朋友,所以请你帮助 Lweb ,寻找一种最优的填写单词方案,使得他
    记住这 n 个单词的情况下,吃最少的泡椒。
     

    Input

    输入一个整数 n ,表示 Lweb 要学习的单词数。接下来 n 行,每行有一个单词(由小写字母构成,且保证任意单
    词两两互不相同)1≤n≤100000, 所有字符的长度总和 1≤|len|≤510000
     

    Output

     Lweb 吃的最少泡椒数

     

    Sample Input

    2
    a
    ba

    Sample Output

    2
     
    这道题的题目意思是:

    给你n个字符串,不同的排列有不同的代价,代价按照如下方式计算(字符串s的位置为x):

    1.排在s后面的字符串有s的后缀,则代价为n^2;

    2.排在s前面的字符串有s的后缀,且没有排在s后面的s的后缀,则代价为x-y(y为最后一个与s不相等的后缀的位置);

    3.s没有后缀,则代价为x。

    根据后缀的条件,我们可以判断出这道题可以用trie树。当然我们需要反向存字符串。

    然后我们可以知道,对于一个字符串,只有它的第一个点(翻转之前)是对我们有用的,比如:ABCD,BCD我们只用记录A有一条向B的边。

    我们先正常建树,然后标记所有末尾点,如果这个点的父亲是它的前缀,那么就连一条父亲到他的边。

    对于取字符策略,考虑贪心。对于一个点,我们优先选择那个最小的子树,从小到大,依次枚举。

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define REP(i,k,n) for(long long i=k;i<=n;i++)
    #define in(a) a=read()
    #define MAXN 510010
    using namespace std;
    inline long long read(){
        long long x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar())
            if(ch=='-')
                f=-1;
        for(;isdigit(ch);ch=getchar())
            x=x*10+ch-'0';
        return x*f;
    }
    long long n;
    long long cnt=1;
    long long f[MAXN];
    long long total=0,head[MAXN],nxt[MAXN],to[MAXN];
    long long tree[MAXN][26],isend[MAXN];
    long long size[MAXN];
    long long dfn[MAXN],ind=0,ans=0;
    long long top=0;
    struct node{
        long long si,in;
    }arr[MAXN];
    inline void adl(long long a,long long b){
        total++;
    //    cout<<total<<" "<<a<<" "<<b<<endl;
        to[total]=b;
        nxt[total]=head[a];
        head[a]=total;
        return ;
    }
    inline void insert(char *s){
        long long u=1;
        for(long long i=strlen(s)-1;i>=0;i--){
            if(!tree[u][s[i]-'a'])  tree[u][s[i]-'a']=++cnt;
            u=tree[u][s[i]-'a'];
        }
        //cout<<u<<endl;
        isend[u]=1;
        return ;
    }
    inline void build(long long u,long long f){
        if(isend[u]){
            adl(f,u);
            f=u;
        }
        REP(i,0,25)
            if(tree[u][i])
                build(tree[u][i],f);
        return ;
    }
    inline void getsize(long long u){
        size[u]=1;
        for(long long e=head[u];e;e=nxt[e]){
            getsize(to[e]);
            size[u]+=size[to[e]];
        }
        return ;
    }
    inline bool cmp(node a,node b){
        return a.si<b.si;
    }
    inline void getans(long long u){
        dfn[u]=++ind;
        long long m=top+1;
        for(long long e=head[u];e;e=nxt[e]){
            arr[++top].in=to[e];
            arr[top].si=size[to[e]];
        }
        if(top<m)  return ;
        sort(arr+m,arr+top+1,cmp);
        REP(i,m,top){
            getans(arr[i].in);
            ans+=dfn[arr[i].in]-dfn[u];
            //cout<<u<<" "<<arr[i].in<<" "<<ans<<endl;
        }
        top=m-1;
        return ;    
    }
    int main(){
        in(n);
        char c[100010];
        REP(i,1,n){
            scanf("%s",c);
            insert(c);
        }
        build(1,1);
        getsize(1);
        getans(1);
        cout<<ans;
    }
    /*
    4
    da
    dcba
    ba
    cba
    */

     

  • 相关阅读:
    [读书笔记]SQLSERVER企业级平台管理实践读书笔记02
    [工作相关] 一个虚拟机上面的SAP4HANA的简单使用维护
    vCenter机器查找功能不可用的解决
    [日常工作]GS使用安装盘修改密码后的处理
    [读书笔记]SQLSERVER企业级平台管理实践读书笔记01
    [书摘]架构真经--可扩展性规则的利益与优先级排行榜
    2017年总结2018年规划
    Windows 通过命令行设置固定ip地址
    ACDsee的安装过程
    [工作相关] GS产品使用LInux下Oracle数据库以及ASM存储时的数据文件路径写法.
  • 原文地址:https://www.cnblogs.com/jason2003/p/9747191.html
Copyright © 2011-2022 走看看