HDU 3336 Count the string (記憶化搜索)

http://acm.hdu.edu.cn/showproblem.php?pid=3336 

 

題意:給定一個長度爲n的字符串(0<n<20000),以n的前k個字符組成一個前序(k = 1,2,3,4.....n),在n中找與前序相同的子序列的個數。

所謂的記憶化搜索,是因爲前一次的搜索對後面的搜索有幫助,就記錄下來,這樣可以減少後面搜索的時間。

 

看看樣例:

abab

前序是 a,ab,aba,abab

建立一個num數組,記錄每一個與前序相同的字串的頭下標。

  a b a b
a 0   2  
ab 0   2  
aba 0      
abab 0      

  num[0] num[1] num[2] num[3]
a 0 2    
ab 0 2    
aba 0      
abab 0      

因爲只有想要與一個前序相同,必先要與上一個前序相同,所以每次只要比較前序最後的一個元素是否與下標爲num[k]加上前序長度的元素相同就可以了。

 

#include <stdio.h>
int main ()
{
	int t,n,i,j,k,sum,all,len;//len是記錄前序長度的
	char ch[200010],ch1,ch2;
	int num[200020],nn;//nn是記錄num數組中元素的個數,每比較完一次元素就更新一次
	scanf ("%d",&t);
	while (t-- > 0)
	{
		len = 0;
		scanf ("%d%c",&n,&ch2);
		gets(ch);
		for (i = 0 ; i < n ; i ++)
			num[i] = i ;
		nn = n;	
		sum = 0;
		for (i = 0 ; i < n ; i ++)
		{
			ch1 = ch[i];
			int ji = 0;
			for (j = 0 ; j < nn ; j ++)
			{
				if (num[j] + len < n && ch1 == ch[num[j] + len] && num[j] + len < n)
				{
					sum ++;
					sum = sum % 10007 ;
					num[ji ++] = num[j];
				}
			}
			nn = ji;
			len ++;
		}
		printf ("%d\n",sum);
	}
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章