17AHU排位赛3 C题 (LCS)

本文介绍了一种通过构建搜索引擎来提高博客内容检索效率的方法。当博客文章数量庞大时,仅依靠标签分类难以高效查找,因此引入了基于最长公共子序列(LCS)算法的搜索机制。通过计算关键词与文章摘要之间的匹配程度,实现精准定位目标文章。
摘要由CSDN通过智能技术生成

problem

博客是一个能非常方便记录自己学习历程的工具,而当你的博客内容非常多的时候,仅仅使用标签和分类已经不足以让你快速定位到要找的博文。
这时,就需要一个搜索引擎来让你更快定位到目标博文。
这里写图片描述
搜索引擎的基本原理就是计算每一个文章与搜索词的相似程度,按照相似程度从大到小显示出来。
经过复杂的代码计算,我们终于解决了字符编码、抛弃冗杂信息的工作,生成了一个每篇文章的摘要信息。现在给你一些关键词,你能找到最符合要求的文章么?
对于文章的匹配程度定义如下:
如果我们将搜索词去除几个单词,剩余的单词按顺序组成一个搜索序列,并且这个序列在摘要中出现了(可以不连续),那么我们就称这个搜索序列与该文章是匹配的。
我们自然希望与该文章匹配搜索序列越长越好,所以搜索词与文章的匹配程度就是上述搜索序列的最长长度

Input

第一行为数据组数T(1<=T<=10)
接下来一行为关键词个数n(1<=n<=100)
紧接着一行是n个英语单词
下面一行是文章个数m(1<=m<=100)
接下来m行每行以一个整数length开头,表示这篇文章的摘要单词数(1<=length<=100)
数据保证对于所有关键单词和摘要单词不超过10个字符,并且只包括小写英语字母

Output

输出最符合要求的文章序号(从1开始计数)
如果最符合要求的文章不唯一,输出序号最小的

Input

1
3
dp search better
3
4 dp is very useful
9 use dp and you can search it in there
6 do better in search with dp

Output

2

Limitation

1s 256MB

Hint

搜索词为dp、search、better
而文章摘要为dp is very useful、use dp and you can search it in there、do better in search with dp
对于第一篇文章摘要:最长的在文章摘要中出现的搜索词序列是dp,所以匹配程度是1
对于第二篇文章摘要:最长的在文章摘要中出现的搜索词序列是dp search,所以匹配程度是2
对于第三篇文章摘要:最长的在文章摘要中出现的搜索词序列是search或者better或者dp,所以匹配程度是1

传送门传送门传送门传送门

思路

裸的LCS,本菜比赛时没有看出来,乱搞没搞出来

关于LCS:点击打开链接


代码示例

#include<bits/stdc++.h>
using namespace std;

const int maxn=110;

int n;//摘要词数

struct w{
    int num;//单词数
    int ans;//匹配数
    vector<string> G;//这个文章的单词
}wen[maxn];//每一篇文章

vector<string> xiang;//待搜索

int dp[maxn][maxn];//dp[len][len]表示两个序列的公共数量

int solve(int loc)
{
    int len1=n;
    int len2=wen[loc].num;
    int i,j;
    for(int i=0;i<=len1;++i) dp[i][0]=0;//无公共子序列
    for(int i=0;i<=len2;++i) dp[0][i]=0;

    for(int i=0;i<len1;++i)
        for(j=0;j<len2;++j){
            if(xiang[i]==wen[loc].G[j]) dp[i+1][j+1]=dp[i][j]+1;
            else{
                dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
            }
        }
    return dp[len1][len2];
}

int main()
{
    ios::sync_with_stdio(false);
    int t,m;//n为待搜索
    cin>>t;
    while(t--)
    {
        //注意初始化
        memset(dp,0,sizeof(dp));
        xiang.clear();
        for(int i=0;i<=maxn;++i){
            wen[i].G.clear();
        }

        cin>>n;
        for(int i=0;i<n;++i){
            string tp;
            cin>>tp;
            xiang.push_back(tp);
        }
        cin>>m;
        string tp;
        int ans=0;
        int maxx=0;
        for(int i=0;i<m;++i){
            cin>>wen[i].num;
            for(int j=0;j<wen[i].num;++j){
                cin>>tp;
                wen[i].G.push_back(tp);
            }
            if(solve(i)>maxx){
                ans=i;
                maxx=solve(i);
            }
        }
        cout<<ans+1<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值