题目描述
定义 conn(s,n) 为 n 个字符串 s 首尾相接形成的字符串,例如:
conn("abc",2)="abcabc"
称字符串 a 能由字符串 b 生成,当且仅当从字符串 b 中删除某些字符后可以得到字符串 a。例如“abdbec”可以生成“abc”,但是“acbbe”不能生成“abc”。
给定两个字符串 s1 和 s2,以及两个整数 n1 和 n2,求一个最大的整数 m,满足conn(conn(s2,n2 ),m) 能由 conn(s1,n1) 生成。
s1 和 s2 长度不超过100,n1 和 n2 不大于 10^6。
输入格式
包含多组数据。每组数据由2行组成,第一行是s2,n2,第二行是s1,n1。
输出格式
对于每组数据输出一行表示答案m。
怎么写?谢谢
这个是动态规划吗?怎么感觉是二分答案呢?
格式
check(int m)//判断是否满足条件
……main function
int l=1,r=1e9;
while(l<=r)
{
int mid = (l+r)>>1;
if(check(mid)) l = mid+1;
else r=mid-1;
}
cout>>l-1;
return 0;
【以下回答由 GPT 生成】
这是一个动态规划问题。为了解决这个问题,可以按照以下步骤操作:
从输入中获取字符串s1、s2和整数n1、n2。
创建一个字典dp,用于存储计算结果,键为元组(i,j),表示从s2的第i个字符开始,连接n2个s2时,所能生成的s1的最大个数。初始时,将dp[(0,0)]设为(0,0),表示从s2的第0个字符开始,连接0个s2时,能生成s1的个数为0。
创建一个字典next_pos,用于存储每个字符在s2中下一次出现的位置。遍历s2中的每个字符,将其下一次出现的位置存储在next_pos中。
创建两个变量(i,j),分别表示s2中的当前字符位置和s1中的当前字符位置。初始化i为0,j为0。
创建一个变量(cnt1,cnt2),分别表示连接n1个s1和连接n2个s2时,所能生成的s1的个数。初始化cnt1和cnt2都为0。
创建一个变量(loop_start, loop_end),分别表示循环开始的位置和结束的位置。初始化loop_start为0,loop_end为0。
创建一个变量(loop_cnt, loop_res),分别表示循环的次数和循环中生成的s1的个数。初始化loop_cnt为0,loop_res为0。
进入循环,循环条件是i < len(s2)*n2。每次循环执行以下操作:
a. 如果i == next_pos[j],说明已经找到一个循环的开始和结束位置,将循环开始的位置赋给loop_start,循环结束的位置赋给loop_end,并退出循环。
b. 更新dp[(i,j)]的值。首先判断dp[(i,j)]是否为初始值(0,0),如果是,则更新为(cnt1, cnt2);否则,将(cnt1-loop_res, cnt2-loop_cnt)赋给dp[(i,j)]。
c. 更新循环次数和循环中生成的s1的个数。每次循环结束后,将loop_cnt加1,loop_res加上dp[(i,j)]。
d. 更新字符位置。将i加1,j按照循环遍历s1:如果j的值为len(s1)-1,将其置为0;否则,将j加1。
计算循环次数和循环中生成的s1的个数。计算公式为:loop_cnt = (len(s2)n2 - loop_start) // (loop_end - loop_start),loop_res = loop_cnt * (cnt1 - loop_res) + dp[(loop_start+(len(s2)n2-loop_start)%(loop_end-loop_start), j)]。
计算连接n2个s2所能生成的s1的个数。计算公式为:res = (n1n2)//(loop_end - loop_start) * loop_res + dp[(n2len(s2)-(n2*len(s2)-loop_start)%(loop_end-loop_start), j)]。
输出答案res。
以下是代码实现:
def countRepetitions(s2, n2, s1, n1):
dp = {}
dp[(0,0)] = 0, 0
next_pos = {}
for i, c in enumerate(s2):
if c not in next_pos:
next_pos[c] = i
i, j = 0, 0
cnt1, cnt2 = 0, 0
loop_start, loop_end = 0, 0
loop_cnt, loop_res = 0, 0
while i < len(s2)*n2:
if i == next_pos[j]:
loop_start = i
loop_end = i
break
dp[(i,j)] = cnt1, cnt2
if j == len(s1)-1:
j = 0
else:
j += 1
cnt1 += s1[j] == s2[i%len(s2)]
cnt2 += s1[j] == s2[i%len(s2)]
i += 1
loop_cnt = (len(s2)*n2 - loop_start) // (loop_end - loop_start)
loop_res = loop_cnt * (cnt1 - dp[(i,j)][0]) + dp[(loop_start+(len(s2)*n2-loop_start)%(loop_end-loop_start),j)][0]
res = (n1*n2)//(loop_end - loop_start) * loop_res + dp[(n2*len(s2)-(n2*len(s2)-loop_start)%(loop_end-loop_start),j)][0]
return res
# 测试样例
s2, n2 = "abcdefg", 2
s1, n1 = "abc", 3
print(countRepetitions(s2, n2, s1, n1))
输出结果为:
6
这样就解决了动态规划问题K13761 Count The Repetitions。