zoukankan      html  css  js  c++  java
  • UVA 10602 Editor Nottoobad

    UVA_10602

        这个题目可以用贪心去做。

        我们不妨先看一下这样一个贪心的思路,每次我们都去拼需要press的字符数最少的单词,这样做是否可以呢?实际上我们可以找到这样一个反例,

        3

        aaaab

        aaaabbb

        aaaac

        如果按这样的贪心思路就会输出

        9

        aaaab

        aaaac

        aaaabbb

        但实际上正确的结果为

        8

        aaaab

        aaaabbb

        aaaac

        尽管上面的想法是错误的,但我们也或多或少会得到些启发,对于这组测试数据之所以没有最优,是由于相比最优的结果多press了一个b,而之所以多press了这个b,是由于我们一开始没有去拼和aaaab有最大前缀的aaaabbb,而选择了去拼aaaac,换句话说,我们press的字符的数量是由相邻的字符串的公共前缀的大小决定的,如果按公共前缀先长后短的顺序去拼字符串,那么后面短了的部分是不会影响press的字符数的,然而如果先拼公共前缀短的字符串,我们就会付出更多的press的代价,而这部分代价就是短的公共前缀变成长的公共前缀所需press的字符数。

        因此,正确的贪心策略是每次选取公共前缀最长的字符串去拼。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 110
    #define INF 0x3f3f3f3f
    int N, g[MAXD][MAXD], vis[MAXD], p[MAXD];
    char b[MAXD][MAXD];
    void solve()
    {
    int i, j, k, t, cur, ans, max;
    scanf("%d", &N);
    for(i = 0; i < N; i ++)
    scanf("%s", b[i]);
    cur = p[0] = 0;
    ans = strlen(b[0]);
    memset(vis, 0, sizeof(vis));
    for(i = 1; i < N; i ++)
    {
    vis[cur] = 1;
    max = -1;
    for(j = 0; j < N; j ++)
    if(!vis[j])
    {
    for(k = 0; b[cur][k] && b[j][k] && b[cur][k] == b[j][k]; k ++);
    if(k > max)
    {
    max = k;
    t = j;
    }
    }
    ans += strlen(b[t]) - max;
    cur = p[i] = t;
    }
    printf("%d\n", ans);
    for(i = 0; i < N; i ++)
    printf("%s\n", b[p[i]]);
    }
    int main()
    {
    int t;
    scanf("%d", &t);
    while(t --)
    {
    solve();
    }
    return 0;
    }


  • 相关阅读:
    置顶功能改进
    Skin设计小组新作品发布—绿草蓝天
    代码着色功能改进
    增加了将文章收藏至网摘的功能
    [公告]C++博客开通
    [新功能]显示文章所属分类
    新Skin发布
    北京.NET俱乐部活动公告
    正式开始学习.NET 2.0
    关于共同学习.NET 2.0的想法
  • 原文地址:https://www.cnblogs.com/staginner/p/2309096.html
Copyright © 2011-2022 走看看