码迷,mamicode.com
首页 > 其他好文 > 详细

FOJ Problem 2254 英语考试

时间:2017-07-16 23:28:12      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:组成   crt   专业   const   time   cost   using   namespace   else   

                                                                                                                                                                                    Problem 2254 英语考试

Accept: 36    Submit: 73
Time Limit: 1000 mSec    Memory Limit : 32768 KB

技术分享 Problem Description

在过三个礼拜,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,因为首先你要背出第一个单词,之后再找单词与单词之间的联系。

AC代码:

#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
using namespace std;
#define INF 0x3f3f3f3f
const int N_MAX = 1000 + 2;
int n, m, w;
string s[N_MAX];
int cost[N_MAX][N_MAX];
int mincost[N_MAX];
bool used[N_MAX];
int V;
int prim() {
    for (int i = 0; i < n;i++) {
        mincost[i] = INF;
        used[i] = false;
    }
    mincost[0] = 0;
    int res = 0;
    while (true) {
        int v = -1;
        for (int u = 0; u < n;u++) {
            if (!used[u] && (v == -1 || mincost[u] < mincost[v]))v = u;
        }
        if (v == -1)break;
        used[v] = true;
        res += mincost[v];
        for (int u = 0; u < n;u++) {
            mincost[u] = min(mincost[u],cost[v][u]);
        }
    }
    return res;
}
int main() {
     while (scanf("%d%d%d",&n,&m,&w)!=EOF) {
        for (int i = 0; i < n; i++)
            cin >> s[i];

        for (int i = 0; i < n;i++) {
            for (int j = 0; j < n;j++) {
                if (i == j)cost[i][j] = INF;
                else {
                    int sum = 0;
                    for (int k = 0; k < m; k++)
                        if (s[i][k] != s[j][k])sum++;
                    cost[i][j]=cost[j][i] = min(m,sum*w);
                }
            }
        }
        printf("%d\n",prim()+m);//!!加上m是因为一开始需要精力背下第一个单词,再找最小生成树
    }
    return 0;
}

 

FOJ Problem 2254 英语考试

标签:组成   crt   专业   const   time   cost   using   namespace   else   

原文地址:http://www.cnblogs.com/ZefengYao/p/7192251.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!