在过三个礼拜,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。
题意中文容易理解
思路:好题,转化为最小生成树来做,每两个单词的权值为min(m,hamming(Si, T) * w),暴力求解任意两个单词的权值,在计算最小生成树之前结果应先加上m,因为第一个单词总是需要m精力来背,其余n-1个单词所需的最小精力则用krusk算法来求
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string.h>
#include<stack>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
//const int MAXN = ;
char a[1005][15];
int n, m, w;
struct node {
int u;
int v;
int w;
}e[1005 * 1005];
bool cmp(struct node n1, struct node n2) {
return n1.w < n2.w;
}
int pre[1005];
int find(int x) {
return pre[x] == x ? x : (pre[x] = find(pre[x]));
}
int merge(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) {
pre[fy] = fx;
return 1;
}
else {
return 0;
}
}
int cal(int i,int j) {
int count = 0;
for (int k = 0; k<m; k++) {
if (a[i][k] != a[j][k]) {
count++;
}
}
return min(m, count*w);
}
int main(void) {
while (scanf("%d%d%d", &n, &m, &w) != EOF) {
for (int i = 0; i < n; i++) {
scanf("%s", a[i]);
}
int con1 = 0;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
e[con1].u = i;
e[con1].v = j;
e[con1++].w = cal(i, j);
//printf("%d %d %d\n", i, j, e[con1 - 1].w);
}
}
sort(e, e + con1, cmp);
for (int i = 0; i <= n; i++) {
pre[i] = i;
}
int con2 = 0;
int ans = m;
for (int i = 0; i < con1; i++) {
if (merge(e[i].u, e[i].v)) {
con2++;
ans += e[i].w;
}
if (con2 == n - 1) {
break;
}
}
printf("%d\n", ans);
}
getchar();
getchar();
return 0;
}