Codeforces Round #267 (Div. 2)D(DFS+单词hash+简单DP)

本文介绍了一个通过替换同义词来最小化英语作文中特定字母出现次数的问题。目标是在保持作文意义不变的前提下,尽可能减少字母'R'的数量,并在此基础上进一步减少作文的整体长度。文章讨论了输入格式、输出要求及解决这一问题的算法思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

D. Fedor and Essay
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

After you had helped Fedor to find friends in the «Call of Soldiers 3» game, he stopped studying completely. Today, the English teacher told him to prepare an essay. Fedor didn't want to prepare the essay, so he asked Alex for help. Alex came to help and wrote the essay for Fedor. But Fedor didn't like the essay at all. Now Fedor is going to change the essay using the synonym dictionary of the English language.

Fedor does not want to change the meaning of the essay. So the only change he would do: change a word from essay to one of its synonyms, basing on a replacement rule from the dictionary. Fedor may perform this operation any number of times.

As a result, Fedor wants to get an essay which contains as little letters «R» (the case doesn't matter) as possible. If there are multiple essays with minimum number of «R»s he wants to get the one with minimum length (length of essay is the sum of the lengths of all the words in it). Help Fedor get the required essay.

Please note that in this problem the case of letters doesn't matter. For example, if the synonym dictionary says that word cat can be replaced with word DOG, then it is allowed to replace the word Cat with the word doG.

Input

The first line contains a single integer m (1 ≤ m ≤ 105) — the number of words in the initial essay. The second line contains words of the essay. The words are separated by a single space. It is guaranteed that the total length of the words won't exceed 105 characters.

The next line contains a single integer n (0 ≤ n ≤ 105) — the number of pairs of words in synonym dictionary. The i-th of the next n lines contains two space-separated non-empty words xi and yi. They mean that word xi can be replaced with word yi (but not vise versa). It is guaranteed that the total length of all pairs of synonyms doesn't exceed 5·105 characters.

All the words at input can only consist of uppercase and lowercase letters of the English alphabet.

Output

Print two integers — the minimum number of letters «R» in an optimal essay and the minimum length of an optimal essay.

Sample test(s)
input
3
AbRb r Zz
4
xR abRb
aA xr
zz Z
xr y
output
2 6
input
2
RuruRu fedya
1
ruruRU fedor
output
1 10

题意:先给出一些单词,然后再给出一个字典,一对一对给出,代表前面的单词可以被后面的替换

            然后要求的是,将原来给出的单词用字典里的单词替换,使得含的R字符最少,如果有多种情况还要使得总字符数最少

思路:先给每种单词hash一下,可以用map实现

            然后将每种单词的R字符数算出来,记为R[i],将每种单词的长度计算出来,记为L[i]

            然后就是简单DP了,dp[i]表示单词 i 的最优的替换的单词,这里的 i 是单词hash后的值

            这个DP可以用DFS来暴搜,先给所有单词按最优值排序,然后按顺序暴搜就好了,搜过的单词就不要重复搜了,会超时的

            然后注意一下建边,如果单词 i 能被单词 j 替换,则从 j 向 i 连一条边

            最后注意的是结果要用long long

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

typedef long long ll;
mapmp;
string s[100010];
int R[100010*3];
int L[100010*3];
int has[100010*3];
int vis[100010*3];
vectorq[100010*3];

void ok(int u,int v)
{
    if(R[has[u]]>R[has[v]]){
        has[u]=has[v];
    }
    else if(R[has[u]]==R[has[v]] && L[has[u]]>L[has[v]]){
        has[u]=has[v];
    }
}

void dfs(int u)
{
    if(vis[u])return;
    vis[u]=1;
    int l=q[u].size();
    for(int i=0;i>s[i];

        for(int j=0;s[i][j];j++){
            if(s[i][j]<='Z'){
                s[i][j]+=32;
            }
        }
        if(mp[s[i]]==0){
            mp[s[i]]=++sz;

            int cnt=0;
            int len=0;
            for(int j=0;s[i][j];j++){
                if(s[i][j]=='r')++cnt;
                ++len;
            }
            R[sz]=cnt;
            L[sz]=len;
        }
    }

    scanf("%d",&n);

    string s1,s2;
    for(int i=0;i>s1>>s2;

        for(int j=0;s1[j];j++){
            if(s1[j]<='Z'){
                s1[j]+=32;
            }
        }

        for(int j=0;s2[j];j++){
            if(s2[j]<='Z'){
                s2[j]+=32;
            }
        }

        if(mp[s1]==0){
            mp[s1]=++sz;

            int cnt=0;
            int len=0;
            for(int j=0;s1[j];j++){
                if(s1[j]=='r')++cnt;
                ++len;
            }
            R[sz]=cnt;
            L[sz]=len;
        }
        if(mp[s2]==0){
            mp[s2]=++sz;

            int cnt=0;
            int len=0;
            for(int j=0;s2[j];j++){
                if(s2[j]=='r')++cnt;
                ++len;
            }
            R[sz]=cnt;
            L[sz]=len;
        }

        int u=mp[s1];
        int v=mp[s2];

        if(u!=v)q[v].push_back(u);
    }

    for(int i=1;i<=sz;i++)has[i]=i;

    for(int i=1;i<=sz;i++){
        vex[i].R=R[i];
        vex[i].L=L[i];
        vex[i].u=i;
    }

    sort(vex+1,vex+sz+1,cmp);
    for(int i=1;i<=sz;i++){
        int x=vex[i].u;
        dfs(x);
    }

    ll ans1=0;
    ll ans2=0;
    for(int i=0;i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值