C语言记忆化搜索___Count the string(Hdu 3336)

Problem Description

It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of this string. For example:

s: "abab"

The prefixes are: "a", "ab", "aba", "abab"

For each prefix, we can count the times it matches in s. So we can see that prefix "a" matches twice, "ab" matches twice too, "aba" matches once, and "abab" matches once. Now you are asked to calculate the sum of the match times for all the prefixes. For "abab",
it is 2 + 2 + 1 + 1 = 6.

The answer may be very large, so output the answer mod 10007.

Input

The first line is a single integer T, indicating the number of test cases.

For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.

Output

For each case, output only one number: the sum of the match times for all the prefixes of s mod 10007.

Sample Input

1
4
abab

Sample Output

6

题意:对于一个字符串,有固定的前缀子串,比如:"abab"的前缀子串有:“a”"ab""aba""abab";然后每个子串跟字符串匹配,求所有子串匹配成功次数.

分析:

可以采用记忆化搜索,用数组b来记录与前一个前缀串匹配的所有字串的最后一个字符。

第一次时记录下b,以后每次只要用a[b[j]+1]与最后一个字符去匹配

#include<stdio.h>
int b[200001];
char a[200001];
int main()
{
	int t,n,k,i,sum,ru,j;
	char pos;
	while(scanf("%d",&t)!=EOF)
	{
		while(t--)
		{
			scanf("%d",&n);
			scanf("%s",a);
			sum=0;
			k=0;
			pos=a[0];
			for(i=0;i<n;i++)
			{
				if(a[i]==pos)
				{
					sum++;
					b[k++]=i;
				}
			}
			sum=sum%10007;
			for(i=1;i<n;i++)
			{
				ru=k;
				k=0;
				pos=a[i];
				for(j=0;j<ru;j++)
				{
					if(a[b[j]+1]==pos)
					{
						sum++;
						b[k++]=b[j]+1;
					}
				}
				sum=sum%10007;
			}
			printf("%d\n",sum);
		}
	}
	return 0;
}

时间: 2024-08-28 17:20:29

C语言记忆化搜索___Count the string(Hdu 3336)的相关文章

C语言记忆化搜索___漫步校园(Hdu 1428)

Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每次从寝室到机房的时间,在校园里散散步.整个HDU校园呈方形布局,可划分为n*n个小方格,代表各个区域.例如LL居住的18号宿舍位于校园的西北角,即方格(1,1)代表的地方,而机房所在的第三实验楼处于东南端的(n,n).因有多条路线可以选择,LL希望每次的散步路线都不一样.另外,他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近(

C语言记忆化搜索___Play Game(Hdu 4597)

Play Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 822    Accepted Submission(s): 474 Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N card

UVA 10981 - String Morphing(记忆化搜索)

题目链接:10981 - String Morphing 题意:给定开始的字符串,要求根据表格变化成一个字符串,问变化的顺序(注意,不一定要最少步数) 思路:记忆化搜索,用map来存字符串的状态,一开始按最少步数去做TLE,其实只要找到一个符合的就可以了 代码: #include <stdio.h> #include <iostream> #include <string.h> #include <string> #include <map> u

Count the string(记忆化搜索)

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4899    Accepted Submission(s): 2313 题目连接 Problem Description It is well known that AekdyCoin is good at string problems as well

UVA - 10559 Blocks 和 Vasya and Binary String CodeForces - 1107E (dp OR 记忆化搜索)

UVA - 10559 Blocks 题意:消消乐,每次连续相同的可以消除,分数加上长度的平方,问最多可以获得几分全部消完 题解: 区间dp + 记忆化搜索 dp[i][j][k] : (区间 [i,  j] 后面带上一段和 j 颜色相同的且长度为 k )的消消乐最大积分 1.消最后一段颜色和 j 颜色相同的 dp[i][j][k] <-- dp[i][j-1][0] + (k+1)^2 2.对于i <= l < j, 如果 l 和 j 的颜色相同, 那么可以把 [l+1, j-1]消掉

HDU 2476 String painter(记忆化搜索, DP)

题目大意: 给你两个串,有一个操作! 操作时可以把某个区间(L,R) 之间的所有字符变成同一个字符.现在给你两个串A,B要求最少的步骤把A串变成B串. 题目分析: 区间DP, 假如我们直接想把A变成B,那么我们DP区间的时候容易产生一个问题:假如我这个区间更新了,那么之前这个区间的子区间内DP出来的值就没用. 然后考虑到这里一直想不过去.最后看了看题解才知道. 我们可以先预处理一下怎么将一个空串变成B串需要的操作数. 这样我们就不用考虑子区间被覆盖的情况了. 如区间L,R 我们需要考虑的是点L是

codeforces1202B You Are Given a Decimal String... 记忆化搜索或Floyd最短路算法

网址:http://codeforces.com/problemset/problem/1202/B 题意: 这个题真的挺绕的,草(中日双语),就是给出一串序列,然后你可以往里面填数,使得填数后的序列可以被$x-y$计数器输出.$x-y$计数器的工作方式是:初始是$0$,每一步加上$x$或者加上$y$,然后输出对$10$取余的数.输出$0<x,y<10$的$x-y$计数器下需要添加的字符数最小值,若无法满足输出$-1$. 题解: 草,比赛时靠着网上的资料一步步写出的记忆化搜索的方法,想不出正解

HDU 1513 Palindrome:LCS(最长公共子序列)or 记忆化搜索

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 题意: 给你一个字符串s,你可以在s中的任意位置添加任意字符,问你将s变成一个回文串最少需要添加字符的个数. 题解1(LCS): 很神奇的做法. 先求s和s的反串的LCS,也就是原串中已经满足回文性质的字符个数. 然后要变成回文串的话,只需要为剩下的每个落单的字符,相应地插入一个和它相同的字符即可. 所以答案是:s.size()-LCS(s,rev(s)) 另外,求LCS时只会用到lcs[i-

uva 1076 - Password Suspects(AC自动机+记忆化搜索)

题目链接:uva 1076 - Password Suspects 题目大意:有一个长度为n的密码,存在m个子串,问说有多少种字符串满足,如果满足个数不大于42,按照字典序输出. 解题思路:根据子串构建AC自动机,然后记忆化搜索,dp[i][u][s]表示第i个字符,在u节点,匹配s个子串. #include <cstdio> #include <cstring> #include <queue> #include <string> #include <