LightOJ 1025 The Specials Menu(记忆化搜索)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1025

题意:给定一个字符串,删除一些字母可以使得该串变成回文串。有多少种删法?

思路:f[i][j]表示[i,j]之间形成回文串有多少种删法。

(1)i==j:f[i][j]=1;

(2)s[i]!=s[j]:f[i][j]=f[i+1][j]+f[i][j-1]-f[i+1][j-1];

(3)s[i]==s[j]:f[i][j]=(f[i+1][j]+f[i][j-1]-f[i+1][j-1])+(f[i+1][j-1]+1)(加1是因为中间[i+1,j-1]的全部删掉也是一种)。

 

View Code
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #define int64 long long

 5 using namespace std;

 6 

 7 int C,n,num=0;

 8 char s[65];

 9 int64 f[65][65];

10 

11 int64 DFS(int i,int j)

12 {

13     if(f[i][j]!=-1) return f[i][j];

14     if(i>j) return f[i][j]=0;

15     if(i==j) return f[i][j]=1;

16     if(s[i]==s[j]) f[i][j]=DFS(i+1,j-1)+1;

17     else f[i][j]=0;

18     f[i][j]+=DFS(i,j-1)+DFS(i+1,j)-DFS(i+1,j-1);

19     return f[i][j];

20 }

21 

22 int main()

23 {

24     for(scanf("%d",&C);C--;)

25     {

26         scanf("%s",s);

27         n=strlen(s);

28         memset(f,-1,sizeof(f));

29         printf("Case %d: %lld\n",++num,DFS(0,n-1));

30     }

31     return 0;

32 }

 

 

 

你可能感兴趣的:(menu)