• FZU


    在过三个礼拜,YellowStar有一场专业英语考试,因此它必须着手开始复习。

    这天,YellowStar准备了n个需要背的单词,每个单词的长度均为m。

    YellowSatr准备采用联想记忆法来背诵这n个单词:

    1、如果YellowStar凭空背下一个新词T,需要消耗单词长度m的精力

    2、如果YellowSatr之前已经背诵了一些单词,它可以选择其中一个单词Si,然后通过联想记忆的方法去背诵新词T,需要消耗的精力为hamming(Si, T) * w。

    hamming(Si, T)指的是字符串Si与T的汉明距离,它表示两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。

    由于YellowStar还有大量繁重的行政工作,因此它想消耗最少的精力背诵下这n个单词,请问它最少需要消耗多少精力。

    Input
    包含多组测试数据。

    第一行为n, m, w。

    接下来n个字符串,每个字符串长度为m,每个单词均为小写字母’a’-‘z’组成。

    1≤n≤1000

    1≤m, w≤10

    Output
    输出一个值表示答案。

    Sample Input
    3 4 2
    abch
    abcd
    efgh
    Sample Output
    10
    Hint
    最优方案是:先凭空记下abcd和efgh消耗精力8,在通过abcd联想记忆去背诵abch,汉明距离为1,消耗为1 * w = 2,总消耗为10。

    思路:将单词看做点,背单词的精力(花费)看做边权,要每个单词都背下来的最小花费,即最小生成树。判断一下是用联想的花费小,还是直接背m的花费小,建立最小边权的图。跑一遍最小生成树即可。

    #include<stdio.h>
    #include<string.h>
    #include<vector>
    using namespace std;
    const int maxn=1e3+10;
    int n,m,w;
    char str[maxn][15];
    short int mp[maxn][maxn];
    int dis(char a[],char b[])
    {
        int sum=0;
        for(int i=0;i<m;i++)if(a[i]!=b[i])sum++;
        return sum;
    }
    int prim()
    {
        bool vis[maxn];
        int dist[maxn];
        memset(vis,false,sizeof(vis));
        memset(dist,0x7f,sizeof(dist));
        vis[0]=true;
        int minn,mini,sum=0;
        for(int i=1; i<n; i++)dist[i]=mp[0][i];
        for(int i=1; i<n; i++)
        {
            int minn=0x7fffffff;
            int mini=-1;
            for(int j=0; j<n; j++)
            {
                if(!vis[j]&&dist[j]<minn)
                {
                    minn=dist[j];
                    mini=j;
                }
            }
            sum+=minn;
            vis[mini]=true;
            for(int j=0; j<n; j++)
                if(!vis[j]&&mp[mini][j]<dist[j]) dist[j]=mp[mini][j];
        }
        return sum;
    }
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&w)!=EOF)
        {
            for(int i=0;i<n;i++)
            {
                scanf("%s",str[i]);
                for(int j=0;j<i;j++)
                {
                    int tmp=dis(str[i],str[j])*w;
                    mp[i][j]=mp[j][i]=tmp>m?m:tmp;
                }
            }
            printf("%d
    ",prim()+m);
        }
    }
    
  • 相关阅读:
    自考 exec 7 3
    画函数图像
    Exec68
    applet main共存 五角星和五面形
    jcheckbox 用例
    JList 单击 ,双击例
    web性能优化(一)弱请求处理
    web性能优化(二)优化思维图
    算法之道左右旋转字符串
    腾讯微信面试题实现时间复杂度为O(1)的栈 20130226
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135757.html
Copyright © 2020-2023  润新知