首页 > 其他分享 >题解:SP10502 VIDEO - Video game combos

题解:SP10502 VIDEO - Video game combos

时间:2024-07-15 18:40:23浏览次数:17  
标签:combos int 题解 tr Trie game tag fail 节点

大意

构造一个长度为 \(k\)(\(k\) 是给定的)的串 \(x\),使得对于 \(∀ 1 \leq i \leq n , s_i\)在 \(x\) 中的出现次数之和最大。

输出这个最大值。

思考

考虑对 \(s_i\)建 AC 自动机,然后 dp。

记 \(dp[i][u]\) 表示为长度为 \(i\) 的字符串,且当前已计算的节点是 Trie 上的编号为 \(u\) 的节点的最大得分。

记 \(tag[k]\) 表示在 Trie 以点 \(k\) 为结尾的字符串的个数。

然后将 \(tag\) 下传。

则转移方程为:

for (int i = 0; i < m; ++i)
		for (int j = 0; j <= cnt; ++j)
			for (int k = 0; k < 3; ++k)
				dp[i + 1][tr[j][k]] = max(dp[i + 1][tr[j][k]], dp[i][j] + tag[tr[j][k]]);

注意这里是以 \(0\) 为 Trie 的根节点。

\(m\) 是读入的 \(k\)。

\(cnt\) 是 Trie 上的节点个数。

答案为:

	for (int i = 0; i <= cnt; ++i)
		ans = max(ans, dp[m][i]);

Code

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

#define int long long

inline int read()
{
	char tr = getchar();
	int x = 0;
	while (tr < '0' || tr > '9')
		tr = getchar();
	while (tr >= '0' && tr <= '9')
		x = x * 10 + tr - '0', tr = getchar();
	return x;
}

#define _ (int)1e5 + 7

int n, m, cnt, tr[_][3], dp[2000][500], fail[_];

int tag[_];

char str[_];

void insert(char *str)
{
	int now = 0;
	int len = strlen(str);
	for (int i = 0; i < len; ++i)
	{
		int p = str[i] - 'A';
		if (!tr[now][p])
			tr[now][p] = ++cnt;
		now = tr[now][p];
	}
	tag[now]++;
}

void get_fail()
{
	queue<int> q;
	for (int i = 0; i < 3; ++i)
		if (tr[0][i])
		{
			fail[tr[0][i]] = 0;
			q.push(tr[0][i]);
		}
	while (!q.empty())
	{
		int u = q.front();
		q.pop();
		for (int i = 0; i < 3; ++i)
			if (tr[u][i])
			{
				fail[tr[u][i]] = tr[fail[u]][i];
				q.push(tr[u][i]);
			}
			else
				tr[u][i] = tr[fail[u]][i];
		tag[u] += tag[fail[u]];
	}
}

signed main()
{
	n = read();
	m = read();
	for (int i = 1; i <= n; ++i)
	{
		scanf("%s", str);
		insert(str);
	}
	get_fail();
	int ans = 0;
	for(int i = 0; i < m; ++i)
		for(int j = 1; j <= cnt; ++j) dp[i][j] = INT_MIN;
	for (int i = 0; i < m; ++i)
		for (int j = 0; j <= cnt; ++j)
			for (int k = 0; k < 3; ++k)
				dp[i + 1][tr[j][k]] = max(dp[i + 1][tr[j][k]], dp[i][j] + tag[tr[j][k]]);
	for (int i = 0; i <= cnt; ++i)
		ans = max(ans, dp[m][i]);
	printf("%lld\n", ans);
}

/*
20 1000
CACAACCCCBACA
ACCACAACC
ACAABCACACCACA
A
CCACAACCCCBACA
BCACACCACAAC
CBACAABCACACCA
CCACAACCCC
CACCACAACCCCBA
AABCACACCA
CCCCBACAAB
ACCACAACCCCBA
ACCACAACCCCBAC
C
CAACCCCBACAA
ACAACCCCBACAAB
CCACAACC
ACAABCACACCACAA
CCACAACCCCBACAA
ACAACCCCBACAABC


1795
*/

标签:combos,int,题解,tr,Trie,game,tag,fail,节点
From: https://www.cnblogs.com/BadBadBad/p/18303746/SP10502

相关文章

  • 【题解】 [CSP-J 2021 T1] 分糖果
    题目描述题目大意给定正整数\(n\)、\(L\)、\(R\),求\(\max_{i\in\left[L,R\right]}{i\bmodn}\)。思路题目主要考察:分类讨论。众所周知,对于\(\forallx\),有$(x\bmodn)\in\left[0,n-1\right]$。可以分为两种情况讨论:如果\(\left\lfloor\frac{L......
  • 题解:CF1833F Ira and Flamenco
    思路因为要一个长度为\(m\)的,且最大与最小的元素之差小于等于\(m\)所以序列应为\(a_i,a_i+1,a_i+2\dots,a_i+m-1\),所以满足要求的序列之需要连续\(m\)个就行了,这个最开始排序,去重后用lower_bound求一下小于\(a_i+m-1\)的数有没有\(m\)个就行了。考虑满足要求序列的......
  • P8704 [蓝桥杯 2020 省 A1] 填空问题 题解
    题目传送门A.跑步训练我们经过仔细观察,可以发现每222分钟就会消耗300300......
  • P2754 [CTSC1999] 家园 / 星际转移问题题解
    开始时,将源点连一条权值为\(k\)的边到地球。然后以时间分层,从上一层的点连接到下一层的点,权值为飞船载人数量,并将代表月球的点连接到汇点。每加一层,在上一层的基础上进行增广,看能不能增加流量,如果流量变为\(k\),那么证明运送完成。可以证明枚举时间最多到\(1500\),图的点数不......
  • 3D 模型在 Game 视图中呈现为 2D效果
    废话不多说,上教程。......
  • SP4063 MPIGS - Sell Pigs / P4638 [SHOI2011] 银行家题解
    考虑使用网络流。建立源点\(S\)和汇点\(T\)。每个人作为一个点,将它们与汇点\(T\)连接,权值为需要的猪的数量。然后对于每个人,如果和之前的某个人开了相同的猪圈,那么就将之前的那个人的点与这个人的点连接。如果猪圈还没有被开过,就从源点\(S\)连接这个点,权值为猪圈猪的初......
  • P1402 酒店之王题解
    考虑使用网络流。分为\(6\)层。第一层为源点。第二层为所有菜的点。第三层和第四层都表示人。(限制只能选择一个)。第五层为房子。第六层为汇点。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=410,M=101000,INF=0x3f3f3f3......
  • AE莫名的小问题解决办法和基础的操作快捷键分享
    更多macOS实用教程,小白教学点击这里!AdobeAfterEffects,简称AE,是由Adobe公司开发的视频剪辑和设计软件。它是一款用于动画、视觉效果和电影合成的二维半动画软件,广泛应用于电影、电视和网络视频创作。AfterEffects主要用于创建动态图像和视觉特效,被誉为制作动态影像设计不可或......
  • 题解 P5270 无论怎样神树大人都会删库跑路
    题解P5270无论怎样神树大人都会删库跑路题意已经说得很清楚了,我们直接开始讲题。首先考虑一次只插入一个字符。问题只在于我们想要判断最后几个字符是否组成相同,即判断两个可重集合是否相等。这个需求很像字符串哈希的目的(快速判断两个字符串是否相等)。但集合怎么哈希呢?需求......
  • [HGAME 2023 week3]kunmusic wp
    今天写了一道Hgame的题,挺有意思的,写个blog记录一下下载附件得到三个文件,先用dnspy打开dll文件,找到main函数,发现为对资源中data的加密。因此将data直接dump下来,对其进行解密,并将解密后的文件保存为111,脚本如下:file=open(r'C:\Users\usr\Desktop\ctf题库\reverse\data','wb')f......