LA3516 Exploring Pyramids
Exploring Pyramids
题目大意:给定一个欧拉序列(即每经过一个点,把这个点加入序列),问有多少种对应的多叉树
序列与树构造对应问题,考虑区间DP
dp[i][j]表示序列i...j对应二叉树个数
初始i == j,dp[i][j] = 1
dp[i][j] = 0,i!=j
转移:dp[i][j] = sum(dp[i + 1][k - 1] * dp[k][j]),s[i] == s[j] 即考虑从i出发,在k这个位置回来,然后再从k出发,到j的时候回来
被MOD卡了一下
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #include <cmath> 9 #define min(a, b) ((a) < (b) ? (a) : (b)) 10 #define max(a, b) ((a) > (b) ? (a) : (b)) 11 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a)) 12 inline void swap(long long &a, long long &b) 13 { 14 long long tmp = a;a = b;b = tmp; 15 } 16 inline void read(long long &x) 17 { 18 x = 0;char ch = getchar(), c = ch; 19 while(ch < '0' || ch > '9') c = ch, ch = getchar(); 20 while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar(); 21 if(c == '-') x = -x; 22 } 23 24 const long long INF = 0x3f3f3f3f; 25 const long long MAXN = 300 + 10; 26 const long long MOD = 1000000000; 27 28 long long dp[MAXN][MAXN],n; 29 char s[MAXN]; 30 31 int main() 32 { 33 while(scanf("%s", s + 1) != EOF) 34 { 35 n = strlen(s + 1); 36 memset(dp, 0, sizeof(dp)); 37 for(register long long i = 1;i <= n;++ i) dp[i][i] = 1; 38 for(register long long k = 1;k <= n;++ k) 39 for(register long long i = 1;i <= n;++ i) 40 { 41 long long j = i + k - 1; 42 if(j > n) break; 43 if(s[i] != s[j]) continue; 44 for(register long long k = i + 2;k <= j;++ k) 45 if(s[i] == s[k]) dp[i][j] += dp[i + 1][k - 1] * dp[k][j] % MOD, dp[i][j] = dp[i][j] >= MOD ? dp[i][j] - MOD : dp[i][j]; 46 } 47 printf("%lld\n", dp[1][n]); 48 } 49 return 0; 50 }