codeforces159D - Palindrome pairs 二重DP

题意:给你一个字符串,问你其中不重叠的回文字串对有多少

解题思路:这题用到两种方法,不过其实是一个很巧妙的二重dp

1)暴力求解以i开头,j结尾的是否为回文,如果是,ans += sum[i-1](ans 为答案, sum[i]为在  1 - i内回文串的个数--需要dp求解)

这里非常耗时,时间大约为  n^3 ,  跑出来为 830ms

解题代码:

 1 // File Name: 159d.cpp
 2 // Author: darkdream
 3 // Created Time: 2014年07月30日 星期三 16时37分50秒
 4
 5 #include<vector>
 6 #include<list>
 7 #include<map>
 8 #include<set>
 9 #include<deque>
10 #include<stack>
11 #include<bitset>
12 #include<algorithm>
13 #include<functional>
14 #include<numeric>
15 #include<utility>
16 #include<sstream>
17 #include<iostream>
18 #include<iomanip>
19 #include<cstdio>
20 #include<cmath>
21 #include<cstdlib>
22 #include<cstring>
23 #include<ctime>
24
25 using namespace std;
26 #define LL long long
27 char str[2005];
28 LL sum[2004];
29 int is(int a,int b)
30 {
31      int k = (a+b)/2;
32      for(int i = a ;i <= k ;i ++ )
33      {
34          if(str[i] != str[b-i+a])
35              return 0 ;
36      }
37      return 1;
38 }
39 int main(){
40     scanf("%s",&str[1]);
41     LL ans = 0 ;
42     int len =  strlen(&str[1]);
43     sum[0] = 0 ;
44     for(int i = 1 ;i <=len ;i ++)
45     {
46          for(int j = 1;j <= i ;j ++)
47          {
48             if(is(j,i))
49             {
50                ans += sum[j-1];
51                sum[i] ++ ;
52             }
53          }
54          sum[i] += sum[i-1];
55     }
56     printf("%I64d\n",ans);
57     return 0;
58 }

2) 这里在前面一种解法上又多了一次dp,因为我们知道了所有情况的以 i 结尾的回文串以后就可以快速求出所有以 i+1 结尾的回文串,所以这里再加一个dp

跑出来时间为  30ms  效率提高了 近30倍

解题代码:

 1 // File Name: 159d.cpp
 2 // Author: darkdream
 3 // Created Time: 2014年07月30日 星期三 16时37分50秒
 4
 5 #include<vector>
 6 #include<list>
 7 #include<map>
 8 #include<set>
 9 #include<deque>
10 #include<stack>
11 #include<bitset>
12 #include<algorithm>
13 #include<functional>
14 #include<numeric>
15 #include<utility>
16 #include<sstream>
17 #include<iostream>
18 #include<iomanip>
19 #include<cstdio>
20 #include<cmath>
21 #include<cstdlib>
22 #include<cstring>
23 #include<ctime>
24
25 using namespace std;
26 #define LL long long
27 char str[2005];
28 LL sum[2004];
29 LL tans[2004];
30 int dp[2000][2000];
31 int main(){
32     scanf("%s",&str[1]);
33     LL ans = 0 ;
34     int len =  strlen(&str[1]);
35     memset(tans,0,sizeof(tans));
36     for(int i = 1;i <= len ;i ++)
37         dp[i][0] = 0;
38     sum[0] = 0 ;
39     dp[1][1] = 1;
40     tans[1] = 1;
41     sum[1] = 1;
42     for(int i = 2 ;i <=len ;i ++)
43     {
44          dp[i][1] = 1;
45          tans[i] = 1;
46          ans += sum[i-1];
47          for(int j = 0;j <= tans[i-1];j ++)
48          {
49               if(str[i-dp[i-1][j]-1] == str[i])
50               {
51                  ans += sum[i-dp[i-1][j]-2];
52                  tans[i] ++ ;
53                  dp[i][tans[i]] = dp[i-1][j] + 2;
54               }
55          }
56          sum[i] = sum[i-1] + tans[i];
57     }
58 //    printf("%I64d\n",tans[2]);
59     printf("%I64d\n",ans);
60     return 0;
61 }

codeforces159D - Palindrome pairs 二重DP

时间: 2024-10-13 10:46:28

codeforces159D - Palindrome pairs 二重DP的相关文章

DP VK Cup 2012 Qualification Round D. Palindrome pairs

题目地址:http://blog.csdn.net/shiyuankongbu/article/details/10004443 1 /* 2 题意:在i前面找回文子串,在i后面找回文子串相互配对,问有几对 3 DP:很巧妙的从i出发向两头扩展判断是否相同来找回文串 4 dpr[i] 代表记录从0到i间的回文子串的个数,dpl[i] 代表记录i之后的回文子串个数 5 两两相乘就行了 6 详细解释:http://blog.csdn.net/shiyuankongbu/article/details

[LeetCode]Palindrome Pairs

题目:Palindrome Pairs Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome. Example 1:Given words = ["bat", "tab",

UVA 10453 Make Palindrome(区间简单DP)

题意:给出一个字符串A,求出需要至少插入多少个字符使得这个字符串变成回文串. 思路:设dp[i][j]为使区间[i, j]变成回文串所需要的最少字符个数. 1.A[i] == A[j的情况]那么dp[i][j] = min(dp[i][j], dp[i + 1][j -1]); 2.或者在第j个位置插入一个字符A[i], dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1); 3.或者在第i个位置插入一个字符A[j], dp[i][j] = min(dp[i][j

HDU 4632 Palindrome subsequence(区间dp,回文串,字符处理)

题目 参考自博客:http://blog.csdn.net/u011498819/article/details/38356675 题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. 简单的区间dp,哎,以为很神奇的东西,其实也是dp,只是参数改为区间,没做过此类型的题,想不到用dp,以后就 知道了,若已经知道[0,i],推[0,i+1], 显然还要从i+1 处往回找,dp方程也简单: dp[j][i]=(dp[j+1][i]+dp[j][i-1]+10007-dp[j+1][

POJ 3280 Cheapest Palindrome(区间DP)

 Cheapest Palindrome Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6894   Accepted: 3344 Description Keeping track of all the cows can be a tricky task so Farmer John has installed a system to automate it. He has installed on each co

lightoj-1044 - Palindrome Partitioning(区间dp)

1044 - Palindrome Partitioning PDF (English) Statistics ForumTime Limit: 1 second(s) Memory Limit: 32 MBA palindrome partition is the partitioning of a string such that each separate substring is a palindrome. For example, the string "ABACABA" c

336. Palindrome Pairs

Given a list of unique words. Find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e.words[i] + words[j] is a palindrome. Example 1:Given words = ["bat", "tab", "cat"]Retu

Palindrome Pairs

Given a list of unique words. Find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e.words[i] + words[j] is a palindrome. Example 1:Given words = ["bat", "tab", "cat"]Retu

HDU 4632 Palindrome subsequence (区间dp 容斥定理)

Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/Others) Total Submission(s): 2610    Accepted Submission(s): 1050 Problem Description In mathematics, a subsequence is a sequence that can be derived