BSOJ1477 -- 【算法竞赛】Count The Repetitions

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 20

Sample 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,果然还是太弱了...

代码待填。。。
 

猜你喜欢

转载自www.cnblogs.com/NOI-AKer/p/CountTheRepetitions.html
今日推荐