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

FZU2254 英语考试

时间:2020-05-01 20:49:08      阅读:61      评论:0      收藏:0      [点我收藏+]

标签:name   测试数据   多少   printf   之间   efi   space   答案   数据   

技术图片 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。

 1 #include <iostream>
 2 using namespace std;
 3 #define MAX 1005
 4 
 5 /*
 6     思路:最小生成树的题目 每个字符串看成一个点 各点之间的权值就看 汉明距离*w与字符串长度m之间小的那个值 使用prim算法
 7 */
 8 
 9 char strs[MAX][15];
10 //表示边权值
11 int edges[MAX][MAX];
12 //表示该点是否加入集合
13 int vis[MAX];
14 //表示该点到集合S的最小距离
15 int dist[MAX];
16 int n, m, w;
17 
18 int hamming(int i, int j)
19 {
20     int sum = 0;
21     for (int index = 0; index < m; index++)
22     {
23         if (strs[i][index] != strs[j][index])
24             sum++;
25     }
26     return sum;
27 }
28 
29 int prim()
30 {
31     int ans = 0;
32     //从0点计算用Prim
33     vis[0] = 1;
34     dist[0] = 0;
35     for (int i = 1; i < n; i++)
36     {
37         vis[i] = 0;
38         dist[i] = edges[0][i];
39     }
40     //n个节点选择n-1条边
41     for (int i = 1; i < n; i++)
42     {
43         int c, d = 20;
44         for (int j = 1; j < n; j++)
45         {
46             if (!vis[j] && d > dist[j])
47             {
48                 d = dist[j];
49                 c = j;
50             }
51         }
52         vis[c] = 1;
53         ans += d;
54         //更新dist
55         for (int j = 1; j < n; j++)
56         {
57             if (!vis[j] && edges[c][j] < dist[j])
58             {
59                 dist[j] = edges[c][j];
60             }
61         }
62     }
63     return ans;
64 }
65 
66 int main()
67 {
68     while (~scanf("%d%d%d", &n, &m, &w))
69     {
70         for (int i = 0; i < n; i++)
71         {
72             scanf("%s", strs[i]);
73         }
74         //计算边
75         for (int i = 0; i < n; i++)
76         {
77             for (int j = i; j < n; j++)
78             {
79                 int h = hamming(i, j) * w;
80                 edges[i][j] = edges[j][i] = h > m ? m : h;
81             }
82         }
83         printf("%d\n", prim() + m);
84     }
85 }

FZU2254 英语考试

标签:name   测试数据   多少   printf   之间   efi   space   答案   数据   

原文地址:https://www.cnblogs.com/dlvguo/p/12814391.html

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