Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/Others)
Total Submission(s): 558 Accepted Submission(s): 203
第一次接触,
题意:
一个字符串,有多少个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。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=1010; const int mod=10007; char str[N]; int dp[N][N]; int main(){ //freopen("input.txt","r",stdin); int t,cases=0; scanf("%d",&t); while(t--){ scanf("%s",str); int len=strlen(str); memset(dp,0,sizeof(dp)); for(int i=0;i<len;i++) dp[i][i]=1; for(int i=0;i<len;i++) for(int j=i-1;j>=0;j--){ dp[j][i]=(dp[j][i-1]+dp[j+1][i]-dp[j+1][i-1]+mod)%mod; if(str[i]==str[j]) dp[j][i]=(dp[j][i]+dp[j+1][i-1]+1+mod)%mod; } printf("Case %d: %d\n",++cases,dp[0][len-1]); } return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=1010; const int mod=10007; char str[N]; int dp[N][N]; int DFS(int l,int r){ if(l>r) return 0; if(l==r) return 1; if(dp[l][r]!=-1) return dp[l][r]; dp[l][r]=(DFS(l+1,r)+DFS(l,r-1)-DFS(l+1,r-1)+mod)%mod; if(str[l]==str[r]) dp[l][r]=(dp[l][r]+DFS(l+1,r-1)+1+mod)%mod; return dp[l][r]; } int main(){ //freopen("input.txt","r",stdin); int t,cases=0; scanf("%d",&t); while(t--){ scanf("%s",str+1); int len=strlen(str+1); memset(dp,-1,sizeof(dp)); printf("Case %d: %d\n",++cases,DFS(1,len)); } return 0; }