zoukankan      html  css  js  c++  java
  • 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。

    题解:

    把每个单词看成一个点,建立所有点间的边,边为min(M,hamming(Si, T) * W)。之后就是基础的最小生成树了。

    代码:prim算法

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    const int MAXN = 1005;
    const int INF = 0x3f3f3f3f;
    
    int N,M,W;
    
    struct Edge{
    	int to;
    	int value;
    	int next;
    }E[MAXN*MAXN];
    
    int head[MAXN];
    int top;
    
    void Add(int from,int to,int value){
    	E[++top].next = head[from];
    	head[from] = top;
    	E[top].value = value;
    	E[top].to = to;
    }
    
    char board[MAXN][15];
    
    int Compare(int a,int b){
    	int ans = 0;
    	for(int i=0 ; i<M ; i++){
    		if(board[a][i] != board[b][i])++ans;
    	}
    	return ans;
    }
    
    bool book[MAXN];
    int lenth[MAXN];
    
    int prim(){
    	memset(book,false,sizeof book);
    	memset(lenth,0,sizeof lenth);
    	book[1] = true;
    	int ans = M;
    	for(int i=head[1] ; i ; i=E[i].next){
    		lenth[E[i].to] = E[i].value;
    	}
    	int minL = INF;
    	int mint;
    	for(int i=2 ; i<=N ; i++){
    		for(int j=2 ; j<=N ; j++){
    			if(book[j] == false && lenth[j]<minL){
    				minL = lenth[j];
    				mint = j;
    			}
    		}
    		ans += minL;
    		minL = INF;
    		book[mint] = true;
    		for(int k=head[mint] ; k ; k=E[k].next){
    			if(book[E[k].to] == false && lenth[E[k].to] > E[k].value)lenth[E[k].to] = E[k].value;
    		}
    	}
    	return ans;
    }
    
    void init(){
    	memset(head,0,sizeof head);
    	top = 0;
    }
    
    int main(){
    	
    	while(scanf("%d %d %d",&N,&M,&W)!=EOF){
    		init();
    		for(int i=1 ; i<=N ; i++)scanf("%s",&board[i]);
    		for(int i=1 ; i<=N ; i++){
    			for(int j=i+1 ; j<=N ; j++){
    				int mid = min(M,Compare(i,j)*W);
    				Add(i,j,mid);
    				Add(j,i,mid);
    			}
    		}
    		printf("%d
    ",prim());
    	}
    	
    	return 0;
    } 


  • 相关阅读:
    一个具体的例子学习Java volatile关键字
    JavaScript实现的水果忍者游戏,支持鼠标操作
    记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑
    微信程序开发系列教程(四)使用微信API创建公众号自定义菜单
    微信程序开发系列教程(三)使用微信API给微信用户发文本消息
    Java实现 LeetCode 547 朋友圈(并查集?)
    Java实现 LeetCode 547 朋友圈(并查集?)
    Java实现 LeetCode 547 朋友圈(并查集?)
    Java实现 LeetCode 546 移除盒子(递归,vivo秋招)
    Java实现 LeetCode 546 移除盒子(递归,vivo秋招)
  • 原文地址:https://www.cnblogs.com/vocaloid01/p/9514095.html
Copyright © 2011-2022 走看看