1477 -- 【算法竞赛】Count The Repetitions
Description
定义 conn(s,n) 为 n 个字符串 s 首尾相接形成的字符串,例如:conn("abc",2)="abcabc"
称字符串 a 能由字符串 b 生成,当且仅当从字符串 b 中删除某些字符后可以得到字符串 a。例如“abdbec”可以生成“abc”,但是“acbbe”不能生成“abc”。
给定两个字符串 s_1 和 s_2,以及两个整数 n_1 和 n_2,求一个最大的整数 m,满足conn(conn(s_2,n_2 ),m) 能由 conn(s_1,n_1) 生成。
s_1 和 s_2 长度不超过100,n_1 和 n_2 不大于 10^6。
Input
本题只有1个测试点,包含多组数据。每组数据由2行组成,第一行是s2,n2,第二行是s1,n1。
Output
对于每组数据输出一行表示答案m。Sample Input
ab 2 acb 4 acb 1 acb 1 aa 1 aaa 3 baab 1 baba 11 aaaaa 1 aaa 20Sample Output
2 1 4 7 12字符串?生成?复制子串?删除字符? 目测75%DP,15%搜索,10%神仙算法。。。 看完题目考虑先模拟出conn(s2,n2)和conn(s1,n1),但n1、n2范围过大,只能考虑DP+状态优化,首先想到的状态优化就是倍增(毕竟...) 很容易发现,conn(conn(x,y),z)等同于conn(x,y*z) ∴求“能由conn(s1,n1)生成的conn(conn(s2,n2),m)”中的max(m), 只需求出“能由conn(s1,n1)生成的conn(s2,n2*m)”中的max(n2*m), 那么令n2*m=m’,只需求出max(m’)即可。 但m’<=s1.length()/s2.length()*n1太大,所以用二进制拆分(倍增思想) ∴m’=2^(P(t-1))+2^(P(t-2))+2^(P(t-3))+2^(P(t-4))+...+2^(P(0)), conn(s2,m’)=conn(s2,2^(P(t-1)))+conn(s2,2^(P(t-2)))+conn(s2,2^(P(t-3)))+conn(s2,2^(P(t-4)))+...+conn(s2,2^(P(0))) 共分解t个字符串首尾相接. DP预处理: 设f[i,j]表示从s1[i]开始需f[i,j]个字符才能生成conn(s2,2^j),n1=inf 非常容易/*从书上找到*/推出状态转移方程f[i,j]=f[i,j-1]+f[(i+f[i,j-1])%s1.length(),j-1]; //(引用《算法竞赛进阶指南》)其含义是,在s1无限重复的字符串中(注:n1=inf),从s1[i]开始,先用尽量少的字符生成目标串的前半部分,紧接着在后边再用尽量少的字符生成目标串的后半部分。 然后就是(几句话的)算法: 枚举s1开始位置,求出max(m’),∴max(m)=floor(max(m’)/n2) p.s.基本参考《算法竞赛进阶指南/李煜东著》(ISBN:978-7-83009-313-6)0x57章Page304∽306,果然还是太弱了...
代码待填。。。