[洛谷3041]视频游戏的连击Video Game Combos

题目描述

Bessie is playing a video game! In the game, the three letters 'A', 'B', and 'C' are the only valid buttons. Bessie may press the buttons in any order she likes; however, there are only N distinct combos possible (1 <= N <= 20). Combo i is represented as a string S_i which has a length between 1 and 15 and contains only the letters 'A', 'B', and 'C'.

Whenever Bessie presses a combination of letters that matches with a combo, she gets one point for the combo. Combos may overlap with each other or even finish at the same time! For example if N = 3 and the three possible combos are "ABA", "CB", and "ABACB", and Bessie presses "ABACB", she will end with 3 points. Bessie may score points for a single combo more than once.

Bessie of course wants to earn points as quickly as possible. If she presses exactly K buttons (1 <= K <= 1,000), what is the maximum number of points she can earn?

贝西在玩一款游戏,该游戏只有三个技能键 “A”“B”“C”可用,但这些键可用形成N种(1 <= N<= 20)特定的组合技。第i个组合技用一个长度为1到15的字符串S_i表示。

当贝西输入的一个字符序列和一个组合技匹配的时候,他将获得1分。特殊的,他输入的一个字符序列有可能同时和若干个组合技匹配,比如N=3时,3种组合技分别为"ABA", "CB", 和"ABACB",若贝西输入"ABACB",他将获得3分。

若贝西输入恰好K (1 <= K <= 1,000)个字符,他最多能获得多少分?

输入输出格式

输入格式:

* Line 1: Two space-separated integers: N and K.

* Lines 2..N+1: Line i+1 contains only the string S_i, representing combo i.

输出格式:

* Line 1: A single integer, the maximum number of points Bessie can obtain.

输入输出样例

输入样例#1: 复制
3 7 
ABA 
CB 
ABACB 
输出样例#1: 复制
4 

说明

The optimal sequence of buttons in this case is ABACBCB, which gives 4 points--1 from ABA, 1 from ABACB, and 2 from CB.

很显然的AC自动机+dp,不过dp那块还是调了半天。。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 int n,cnt,ans,k;
 7 int fail[3010];
 8 int end[3010];
 9 int ch[3010][27];
10 int dp[3010][1001];
11 bool vis[3010][1001];
12 char s[100];
13 void build(string s)
14 {
15     int len=s.length();
16     int now=0;
17     for(int i=0;i<len;i++)
18     {
19         if(!ch[now][s[i]-'A']) ch[now][s[i]-'A']=++cnt;
20         now=ch[now][s[i]-'A'];
21     }
22     end[now]+=1;
23 }
24 void build_fail()
25 {
26     queue<int>q;
27     for(int i=0;i<3;i++)
28         if(ch[0][i])
29             q.push(ch[0][i]);
30     while(!q.empty())
31     {
32         int u=q.front(); q.pop();
33         for(int i=0;i<3;i++)
34         {
35             if(ch[u][i])
36             {
37                 fail[ch[u][i]]=ch[fail[u]][i];
38                 q.push(ch[u][i]);
39             }
40             else ch[u][i]=ch[fail[u]][i];
41         }
42     }
43 }
44 int get(int now,int val)
45 {
46     while(now) val+=end[now],now=fail[now];
47     return val;
48 }
49 int main()
50 {
51     scanf("%d%d",&n,&k);
52     for(int i=1;i<=n;i++)
53     {
54         scanf("%s",s);
55         build(s);
56     }
57     build_fail();
58     vis[0][0]=1;
59     for(int i=0;i<k;i++)
60         for(int j=0;j<=cnt;j++)
61         {
62             if(!vis[i][j]) continue;
63             for(int l=0;l<3;l++)
64             {
65                 int now=ch[j][l];
66                 dp[i+1][now]=max(dp[i+1][now],get(now,dp[i][j]));
67                 vis[i+1][now]=true;
68             }
69         }
70     for(int i=0;i<=cnt;i++) ans=max(ans,dp[k][i]);
71     printf("%d",ans);
72     return 0; 
73 }

猜你喜欢

转载自www.cnblogs.com/Slrslr/p/9496647.html