标签:des style blog http java color
http://acm.hdu.edu.cn/showproblem.php?pid=4632
题意:
一个字符串,有多少个subsequence是回文串。
别人的题解:
用dp[i][j]表示这一段里有多少个回文串,那首先dp[i][j]=dp[i+1][j]+dp[i][j-1],但是dp[i+1][j]和dp[i][j-1]可能有公共部分,所以要减去dp[i+1][j-1]。
如果str[i]==str[j]的话,还要加上dp[i+1][j-1]+1。
但是自己却是这样想的,把每个区间都要看是否为回文串,在dp[i][j]=dp[i+1][j]+1。我的想法是错误的,我忽略了每个区间都是一个递推的过程。
比如:aaa,a是一个回文串则外面2个aa只要判断是否相等就可以了就可以。如果区间两头是相等的,则要加上dp[j+1][i-1]+1,因为首尾是可以组成一个回文子串的,而且首尾可以与中间任何一个回文子串组成新的回文子。
其结果要取余,利用来了 dp[i][j]=(dp[i][j]+10007)%10007;
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/Others)
Total Submission(s): 2246 Accepted Submission(s): 895
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int dp[1005][1005]; int main() { int t,k,i,j,g,len,r,p,q,e,m,b; char str[1005]; cin>>q; for(r=1;r<=q;r++) { memset(dp,0,sizeof(dp)); scanf("%s",str); len=strlen(str); for(i=0;i<len;i++) dp[i][i]=1;//初始化,单个字符肯定是一个回文子串 for(k=0;k<len;k++) { for(i=0;i<len-k;i++) { j=i+k; dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1];////如果区间两头是相等的,则要加上dp[j+1][i-1]+1, //因为首尾是可以组成一个回文子串的,而且首尾可以与中间任何一个回文子串组成新的回文子串 if(str[i]==str[j]) dp[i][j]+=dp[i+1][j-1]+1; dp[i][j]=(dp[i][j]+10007)%10007;//结果取余。 } } printf("Case %d: %d\n",r,dp[0][len-1]); } return 0; } /* 4 a aaaaa goodafternooneveryone welcometoooxxourproblems Case 1: 1 Case 2: 31 Case 3: 421 Case 4: 960 */
HDU-4632 http://acm.hdu.edu.cn/showproblem.php?pid=4632,布布扣,bubuko.com
HDU-4632 http://acm.hdu.edu.cn/showproblem.php?pid=4632
标签:des style blog http java color
原文地址:http://www.cnblogs.com/cancangood/p/3863117.html