hdu 4632 Palindrome subsequence

題目連接

 

 

 

題意:找出字符串中所有迴文子序列的個數,最後%10007;

用簡單的DP做,核心是要把每一串迴文子序列都看成一個個體,

 

例如:aebcdbta中 在區間[1,6]中的個體有9個:e,b,c,d,b,t,bcb,bdb,bb;

 

明白這個,這樣就可以dp了,

所以假設在區間dp[ i] [ j ]表示區間[i ,j]中個體的個數;

 

假設字符串S(s1,s2,.....,),在區間[i + 1,j - 1]中的個體是n個,

就可以表示爲s[ i ]    (n)   s[ j ] ;所以有dp[ i ][ j - 1] = n + 1;dp[i + 1][ j ] = n + 1; 

現在要求dp[ i ][ j ]  :1,當s[ i ] == s[ j ] 

                                        dp[ i ] [ j ] =dp[ i ][ j - 1]  +  dp[i + 1][ j ]  + 1;

                               2,當s[i] != s[j]

                                       dp[ i ] [ j ] = dp[ i ][ j - 1]  +  dp[i + 1][ j ]  - dp[i + 1][j - 1]; 

 

 

要注意mod的時候會出現負數要處理。

 

/*
題意:找出字符串中所有迴文子序列的個數,最後%10007

想法:1,把一個區間中的沒有個迴文子序列都看成一個個體 
*/ 



#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

char s[1100];
int pan[1100][1100];
int dp[1100][1100];

int main ()
{
	int i,j,k;
	int t;
	int n;
	cin >> t;
	for (k = 1 ; k <= t ; k ++)
	{
		cin >> s;
		memset (dp,0,sizeof(dp));
		n = strlen (s);
		for (i = 0 ; i < n ; i ++)
		{
			for (j = 0 ; j + i < n ; j ++ )
			{
				if (j == j + i)
					dp[j][j + i] = 1;
				else
				{
					if (s[j] == s[j + i])
						dp[j][j + i] = dp[j][j + i - 1] + dp[j + 1][j + i] + 1;
					else
						dp[j][j + i] = dp[j][j + i - 1] + dp[j + 1][j + i] - dp[j + 1][j + i - 1];
				}
				dp[j][i + j] = (dp[j][j + i] + 10007) % 10007;	
			}
		}
		printf ("Case %d: %d\n",k,dp[0][n - 1]);
	}
}


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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