标签:name 测试数据 多少 printf 之间 efi space 答案 数据
在过三个礼拜,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个单词,请问它最少需要消耗多少精力。
包含多组测试数据。
第一行为n, m, w。
接下来n个字符串,每个字符串长度为m,每个单词均为小写字母‘a‘-‘z‘组成。
1≤n≤1000
1≤m, w≤10
输出一个值表示答案。
最优方案是:先凭空记下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 }
标签:name 测试数据 多少 printf 之间 efi space 答案 数据
原文地址:https://www.cnblogs.com/dlvguo/p/12814391.html